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,1482 @@
|
|
|
1
|
+
<!-- Updated by playbook session 2026-03-18 -->
|
|
2
|
+
# Location Recording, Supervisor, Guest Calling, Conference & Misc
|
|
3
|
+
|
|
4
|
+
**CLI group:** `wxcli call-recording` (org-level recording vendor, compliance, per-location vendor assignment)
|
|
5
|
+
**NOT:** `wxcli location-call-settings` (that group handles dial patterns for premise PSTN — completely different domain)
|
|
6
|
+
|
|
7
|
+
## Sources
|
|
8
|
+
|
|
9
|
+
- wxc_sdk v1.30.0
|
|
10
|
+
- OpenAPI spec: specs/webex-cloud-calling.json
|
|
11
|
+
- developer.webex.com Location Call Settings APIs
|
|
12
|
+
|
|
13
|
+
Reference for advanced location-level and org-level call settings managed through the wxc_sdk. Covers call recording vendors and compliance, caller reputation (spam scoring), conference controls, supervisor/agent management, guest calling (click-to-call), operating modes, hot desking via voice portal, and shared forwarding patterns used across features.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Table of Contents
|
|
18
|
+
|
|
19
|
+
1. [Call Recording](#1-call-recording)
|
|
20
|
+
2. [Caller Reputation](#2-caller-reputation)
|
|
21
|
+
3. [Conference Controls](#3-conference-controls)
|
|
22
|
+
4. [Supervisors](#4-supervisors)
|
|
23
|
+
5. [Guest Calling (Click-to-Call)](#5-guest-calling-click-to-call)
|
|
24
|
+
6. [Operating Modes](#6-operating-modes)
|
|
25
|
+
7. [Hot Desking Sign-in via Voice Portal](#7-hot-desking-sign-in-via-voice-portal)
|
|
26
|
+
8. [Forwarding (Shared Patterns)](#8-forwarding-shared-patterns)
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## 1. Call Recording
|
|
31
|
+
|
|
32
|
+
**SDK module:** `wxc_sdk.telephony.call_recording`
|
|
33
|
+
**API class:** `CallRecordingSettingsApi` (base: `telephony/config`)
|
|
34
|
+
**Not supported** for Webex for Government (FedRAMP). See [authentication.md → FedRAMP](authentication.md#webex-for-government-fedramp) for all FedRAMP restrictions.
|
|
35
|
+
|
|
36
|
+
Call recording supports multiple third-party vendors. The org has an overall default vendor, but individual locations can override to a different vendor.
|
|
37
|
+
|
|
38
|
+
### 1.1 Scopes
|
|
39
|
+
|
|
40
|
+
| Operation | Scope |
|
|
41
|
+
|-----------|-------|
|
|
42
|
+
| Read | `spark-admin:telephony_config_read` |
|
|
43
|
+
| Write | `spark-admin:telephony_config_write` |
|
|
44
|
+
|
|
45
|
+
### 1.2 Data Models
|
|
46
|
+
|
|
47
|
+
#### `CallRecordingInfo`
|
|
48
|
+
Top-level org recording status.
|
|
49
|
+
|
|
50
|
+
| Field | Type | Notes |
|
|
51
|
+
|-------|------|-------|
|
|
52
|
+
| `organization` | `IdAndName` | Org id and name |
|
|
53
|
+
| `enabled` | `bool` | Whether call recording is enabled |
|
|
54
|
+
| `vendor_id` | `str` | Current vendor ID |
|
|
55
|
+
| `vendor_name` | `str` | Current vendor name |
|
|
56
|
+
| `terms_of_service_url` | `str` | Empty for Webex Recording Platform |
|
|
57
|
+
|
|
58
|
+
#### `CallRecordingTermsOfService`
|
|
59
|
+
|
|
60
|
+
| Field | Type | Notes |
|
|
61
|
+
|-------|------|-------|
|
|
62
|
+
| `vendor_id` | `str` | |
|
|
63
|
+
| `vendor_name` | `str` | |
|
|
64
|
+
| `terms_of_service_enabled` | `bool` | |
|
|
65
|
+
| `terms_of_service_url` | `str` | Empty for Webex Recording Platform |
|
|
66
|
+
|
|
67
|
+
#### `OrgComplianceAnnouncement`
|
|
68
|
+
Controls whether the recording START/STOP announcement plays on PSTN calls.
|
|
69
|
+
|
|
70
|
+
| Field | Type | Notes |
|
|
71
|
+
|-------|------|-------|
|
|
72
|
+
| `inbound_pstncalls_enabled` | `bool` | Alias: `inboundPSTNCallsEnabled` |
|
|
73
|
+
| `outbound_pstncalls_enabled` | `bool` | Alias: `outboundPSTNCallsEnabled` |
|
|
74
|
+
| `outbound_pstncalls_delay_enabled` | `bool` | Alias: `outboundPSTNCallsDelayEnabled` |
|
|
75
|
+
| `delay_in_seconds` | `int` | Seconds before announcement plays |
|
|
76
|
+
|
|
77
|
+
**Interaction note:** When the compliance announcement plays to the PSTN party and that party is connected to someone with call recording enabled, the start/stop announcement is inhibited.
|
|
78
|
+
|
|
79
|
+
#### `LocationComplianceAnnouncement` (extends `OrgComplianceAnnouncement`)
|
|
80
|
+
|
|
81
|
+
| Additional Field | Type | Notes |
|
|
82
|
+
|------------------|------|-------|
|
|
83
|
+
| `use_org_settings_enabled` | `bool` | Use org-level defaults |
|
|
84
|
+
|
|
85
|
+
#### `FailureBehavior` (Enum)
|
|
86
|
+
What happens when recording fails:
|
|
87
|
+
|
|
88
|
+
| Value | Behavior |
|
|
89
|
+
|-------|----------|
|
|
90
|
+
| `PROCEED_WITH_CALL_NO_ANNOUNCEMENT` | Call continues, no announcement |
|
|
91
|
+
| `PROCEED_CALL_WITH_ANNOUNCEMENT` | Call continues, announcement plays |
|
|
92
|
+
| `END_CALL_WITH_ANNOUNCEMENT` | Call ends with announcement |
|
|
93
|
+
|
|
94
|
+
#### `RecordingVendor`
|
|
95
|
+
|
|
96
|
+
| Field | Type |
|
|
97
|
+
|-------|------|
|
|
98
|
+
| `id` | `str` |
|
|
99
|
+
| `name` | `str` |
|
|
100
|
+
| `description` | `str` |
|
|
101
|
+
| `migrate_user_creation_enabled` | `bool` |
|
|
102
|
+
| `login_url` | `str` |
|
|
103
|
+
| `terms_of_service_url` | `str` |
|
|
104
|
+
|
|
105
|
+
#### `CallRecordingVendors` (org-level)
|
|
106
|
+
|
|
107
|
+
| Field | Type | Notes |
|
|
108
|
+
|-------|------|-------|
|
|
109
|
+
| `vendor_id` | `str` | Current vendor |
|
|
110
|
+
| `vendor_name` | `str` | |
|
|
111
|
+
| `vendors` | `list[RecordingVendor]` | All available vendors |
|
|
112
|
+
| `storage_region` | `str` | Only for Webex vendor |
|
|
113
|
+
| `failure_behavior` | `FailureBehavior` | |
|
|
114
|
+
|
|
115
|
+
#### `CallRecordingLocationVendors`
|
|
116
|
+
|
|
117
|
+
| Field | Type | Notes |
|
|
118
|
+
|-------|------|-------|
|
|
119
|
+
| `org_default_enabled` | `bool` | |
|
|
120
|
+
| `org_default_vendor_id` | `str` | |
|
|
121
|
+
| `org_default_vendor_name` | `str` | |
|
|
122
|
+
| `default_vendor_id` | `str` | Location-level vendor |
|
|
123
|
+
| `default_vendor_name` | `str` | |
|
|
124
|
+
| `vendors` | `list[RecordingVendor]` | |
|
|
125
|
+
| `org_storage_region_enabled` | `bool` | |
|
|
126
|
+
| `org_storage_region` | `str` | |
|
|
127
|
+
| `storage_region` | `str` | Location-level region |
|
|
128
|
+
| `org_failure_behavior_enabled` | `bool` | |
|
|
129
|
+
| `org_failure_behavior` | `FailureBehavior` | |
|
|
130
|
+
| `failure_behavior` | `FailureBehavior` | Location-level |
|
|
131
|
+
|
|
132
|
+
#### `CallRecordingRegion`
|
|
133
|
+
|
|
134
|
+
| Field | Type |
|
|
135
|
+
|-------|------|
|
|
136
|
+
| `code` | `str` — two-character region code |
|
|
137
|
+
| `name` | `str` |
|
|
138
|
+
| `default_enabled` | `bool` |
|
|
139
|
+
|
|
140
|
+
#### `RecordingUser`
|
|
141
|
+
|
|
142
|
+
| Field | Type |
|
|
143
|
+
|-------|------|
|
|
144
|
+
| `id` | `str` |
|
|
145
|
+
| `first_name` | `str` |
|
|
146
|
+
| `last_name` | `str` |
|
|
147
|
+
| `type` | `UserType` |
|
|
148
|
+
| `license_type` | `UserLicenseType` |
|
|
149
|
+
|
|
150
|
+
### 1.3 API Methods
|
|
151
|
+
|
|
152
|
+
```python
|
|
153
|
+
class CallRecordingSettingsApi:
|
|
154
|
+
|
|
155
|
+
# --- Org-level recording on/off ---
|
|
156
|
+
def read(self, org_id: str = None) -> CallRecordingInfo
|
|
157
|
+
def update(self, enabled: bool, org_id: str = None) # Cisco partners only
|
|
158
|
+
|
|
159
|
+
# --- Terms of service ---
|
|
160
|
+
def read_terms_of_service(self, vendor_id: str, org_id: str = None) -> CallRecordingTermsOfService
|
|
161
|
+
def update_terms_of_service(self, vendor_id: str, enabled: bool, org_id: str = None)
|
|
162
|
+
|
|
163
|
+
# --- Compliance announcement (org) ---
|
|
164
|
+
def read_org_compliance_announcement(self, org_id: str = None) -> OrgComplianceAnnouncement
|
|
165
|
+
def update_org_compliance_announcement(self, settings: OrgComplianceAnnouncement, org_id: str = None)
|
|
166
|
+
|
|
167
|
+
# --- Compliance announcement (location) ---
|
|
168
|
+
def read_location_compliance_announcement(self, location_id: str, org_id: str = None) -> LocationComplianceAnnouncement
|
|
169
|
+
def update_location_compliance_announcement(self, location_id: str, settings: LocationComplianceAnnouncement, org_id: str = None)
|
|
170
|
+
|
|
171
|
+
# --- Regions ---
|
|
172
|
+
def get_call_recording_regions(self, org_id: str = None) -> list[CallRecordingRegion]
|
|
173
|
+
|
|
174
|
+
# --- Vendor users (org) ---
|
|
175
|
+
def list_org_users(self, standard_user_only: bool = None, org_id: str = None, **params) -> Generator[RecordingUser]
|
|
176
|
+
|
|
177
|
+
# --- Vendor management (org) ---
|
|
178
|
+
def get_org_vendors(self, org_id: str = None) -> CallRecordingVendors
|
|
179
|
+
def set_org_vendor(self, vendor_id: str, storage_region: str = None,
|
|
180
|
+
failure_behavior: FailureBehavior = None, org_id: str = None) -> str # returns jobId
|
|
181
|
+
|
|
182
|
+
# --- Vendor management (location) ---
|
|
183
|
+
def get_location_vendors(self, location_id: str, org_id: str = None) -> CallRecordingLocationVendors
|
|
184
|
+
def set_location_vendor(self, location_id: str, id: str = None,
|
|
185
|
+
org_default_enabled: bool = None, storage_region: str = None,
|
|
186
|
+
org_storage_region_enabled: bool = None,
|
|
187
|
+
failure_behavior: FailureBehavior = None,
|
|
188
|
+
org_failure_behavior_enabled: bool = None,
|
|
189
|
+
org_id: str = None) -> str # returns jobId
|
|
190
|
+
|
|
191
|
+
# --- Vendor users (location) ---
|
|
192
|
+
def list_location_users(self, location_id: str, standard_user_only: bool = None,
|
|
193
|
+
org_id: str = None, **params) -> Generator[RecordingUser]
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### 1.4 Raw HTTP — Call Recording
|
|
197
|
+
|
|
198
|
+
```python
|
|
199
|
+
BASE = "https://webexapis.com/v1"
|
|
200
|
+
|
|
201
|
+
# --- Org-level recording on/off ---
|
|
202
|
+
# GET — Get call recording settings
|
|
203
|
+
result = api.session.rest_get(f"{BASE}/telephony/config/callRecording")
|
|
204
|
+
# Response: {"organization": {"id": "...", "name": "..."}, "enabled": true,
|
|
205
|
+
# "vendorId": "...", "vendorName": "...", "termsOfServiceUrl": ""}
|
|
206
|
+
|
|
207
|
+
# PUT — Enable/disable call recording (Cisco partners only)
|
|
208
|
+
body = {"enabled": True}
|
|
209
|
+
api.session.rest_put(f"{BASE}/telephony/config/callRecording", json=body)
|
|
210
|
+
|
|
211
|
+
# --- Terms of service ---
|
|
212
|
+
# GET
|
|
213
|
+
result = api.session.rest_get(f"{BASE}/telephony/config/callRecording/vendors/{vendor_id}/termsOfService")
|
|
214
|
+
# PUT
|
|
215
|
+
body = {"termsOfServiceEnabled": True}
|
|
216
|
+
api.session.rest_put(f"{BASE}/telephony/config/callRecording/vendors/{vendor_id}/termsOfService", json=body)
|
|
217
|
+
|
|
218
|
+
# --- Compliance announcement (org) ---
|
|
219
|
+
# GET
|
|
220
|
+
result = api.session.rest_get(f"{BASE}/telephony/config/callRecording/complianceAnnouncement")
|
|
221
|
+
# Response: {"inboundPSTNCallsEnabled": false, "outboundPSTNCallsEnabled": false,
|
|
222
|
+
# "outboundPSTNCallsDelayEnabled": false, "delayInSeconds": 3}
|
|
223
|
+
|
|
224
|
+
# PUT
|
|
225
|
+
body = {
|
|
226
|
+
"inboundPSTNCallsEnabled": True,
|
|
227
|
+
"outboundPSTNCallsEnabled": True,
|
|
228
|
+
"outboundPSTNCallsDelayEnabled": True,
|
|
229
|
+
"delayInSeconds": 5
|
|
230
|
+
}
|
|
231
|
+
api.session.rest_put(f"{BASE}/telephony/config/callRecording/complianceAnnouncement", json=body)
|
|
232
|
+
|
|
233
|
+
# --- Compliance announcement (location) ---
|
|
234
|
+
# GET
|
|
235
|
+
result = api.session.rest_get(
|
|
236
|
+
f"{BASE}/telephony/config/locations/{loc_id}/callRecording/complianceAnnouncement"
|
|
237
|
+
)
|
|
238
|
+
# Response includes useOrgSettingsEnabled
|
|
239
|
+
|
|
240
|
+
# PUT
|
|
241
|
+
body = {
|
|
242
|
+
"useOrgSettingsEnabled": False,
|
|
243
|
+
"inboundPSTNCallsEnabled": True,
|
|
244
|
+
"outboundPSTNCallsEnabled": True,
|
|
245
|
+
"outboundPSTNCallsDelayEnabled": True,
|
|
246
|
+
"delayInSeconds": 3
|
|
247
|
+
}
|
|
248
|
+
api.session.rest_put(
|
|
249
|
+
f"{BASE}/telephony/config/locations/{loc_id}/callRecording/complianceAnnouncement",
|
|
250
|
+
json=body
|
|
251
|
+
)
|
|
252
|
+
|
|
253
|
+
# --- Regions ---
|
|
254
|
+
# GET
|
|
255
|
+
result = api.session.rest_get(f"{BASE}/telephony/config/callRecording/regions")
|
|
256
|
+
# Response: {"regions": [{"code": "US", "name": "United States", "defaultEnabled": true}]}
|
|
257
|
+
|
|
258
|
+
# --- Vendor users (org) ---
|
|
259
|
+
# GET (paginated)
|
|
260
|
+
result = api.session.rest_get(f"{BASE}/telephony/config/callRecording/vendorUsers",
|
|
261
|
+
params={"max": 1000, "standardUserOnly": True})
|
|
262
|
+
# Response: {"vendorUsers": [...]}
|
|
263
|
+
|
|
264
|
+
# --- Vendor management (org) ---
|
|
265
|
+
# GET — Get org vendors
|
|
266
|
+
result = api.session.rest_get(f"{BASE}/telephony/config/callRecording/vendors")
|
|
267
|
+
|
|
268
|
+
# PUT — Set org vendor (returns jobId)
|
|
269
|
+
body = {"vendorId": "<vendor_id>", "storageRegion": "US", "failureBehavior": "PROCEED_WITH_CALL_NO_ANNOUNCEMENT"}
|
|
270
|
+
result = api.session.rest_put(f"{BASE}/telephony/config/callRecording/vendor", json=body)
|
|
271
|
+
# Response 200: {"jobId": "..."} or 204 for immediate
|
|
272
|
+
|
|
273
|
+
# --- Vendor management (location) ---
|
|
274
|
+
# GET — Get location vendors
|
|
275
|
+
result = api.session.rest_get(f"{BASE}/telephony/config/locations/{loc_id}/callRecording/vendors")
|
|
276
|
+
|
|
277
|
+
# PUT — Set location vendor (returns jobId)
|
|
278
|
+
body = {
|
|
279
|
+
"id": "<vendor_id>",
|
|
280
|
+
"orgDefaultEnabled": False,
|
|
281
|
+
"storageRegion": "US",
|
|
282
|
+
"orgStorageRegionEnabled": False,
|
|
283
|
+
"failureBehavior": "PROCEED_WITH_CALL_NO_ANNOUNCEMENT",
|
|
284
|
+
"orgFailureBehaviorEnabled": False
|
|
285
|
+
}
|
|
286
|
+
result = api.session.rest_put(f"{BASE}/telephony/config/locations/{loc_id}/callRecording/vendor", json=body)
|
|
287
|
+
|
|
288
|
+
# --- Vendor users (location) ---
|
|
289
|
+
# GET (paginated)
|
|
290
|
+
result = api.session.rest_get(
|
|
291
|
+
f"{BASE}/telephony/config/locations/{loc_id}/callRecording/vendorUsers",
|
|
292
|
+
params={"max": 1000, "standardUserOnly": True}
|
|
293
|
+
)
|
|
294
|
+
|
|
295
|
+
# --- Call Recording Jobs ---
|
|
296
|
+
# GET — List jobs
|
|
297
|
+
result = api.session.rest_get(f"{BASE}/telephony/config/jobs/callRecording", params={"max": 100})
|
|
298
|
+
|
|
299
|
+
# GET — Job status
|
|
300
|
+
result = api.session.rest_get(f"{BASE}/telephony/config/jobs/callRecording/{job_id}")
|
|
301
|
+
|
|
302
|
+
# GET — Job errors
|
|
303
|
+
result = api.session.rest_get(f"{BASE}/telephony/config/jobs/callRecording/{job_id}/errors")
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
### 1.5 CLI Examples
|
|
307
|
+
|
|
308
|
+
```bash
|
|
309
|
+
# Get org-level call recording settings
|
|
310
|
+
wxcli call-recording show
|
|
311
|
+
|
|
312
|
+
# Get org-level compliance announcement settings
|
|
313
|
+
wxcli call-recording show-compliance-announcement-call-recording
|
|
314
|
+
|
|
315
|
+
# Enable compliance announcement for inbound PSTN calls with 5-second delay
|
|
316
|
+
wxcli call-recording update-compliance-announcement-call-recording \
|
|
317
|
+
--inbound-pstn-calls-enabled --outbound-pstn-calls-enabled \
|
|
318
|
+
--outbound-pstn-calls-delay-enabled --delay-in-seconds 5
|
|
319
|
+
|
|
320
|
+
# Get location-level compliance announcement settings
|
|
321
|
+
wxcli call-recording show-compliance-announcement-call-recording-1 <location_id>
|
|
322
|
+
|
|
323
|
+
# Get org-level recording vendors
|
|
324
|
+
wxcli call-recording show-vendors
|
|
325
|
+
|
|
326
|
+
# Get location-level recording vendors
|
|
327
|
+
wxcli call-recording list-vendors <location_id>
|
|
328
|
+
|
|
329
|
+
# Set recording vendor for a location
|
|
330
|
+
wxcli call-recording update-vendor-call-recording <location_id> \
|
|
331
|
+
--id <vendor_id> --no-org-default-enabled \
|
|
332
|
+
--storage-region US --no-org-storage-region-enabled
|
|
333
|
+
|
|
334
|
+
# List call recording regions
|
|
335
|
+
wxcli call-recording list
|
|
336
|
+
|
|
337
|
+
# List vendor users at org level (paginated)
|
|
338
|
+
wxcli call-recording list-vendor-users-call-recording
|
|
339
|
+
|
|
340
|
+
# List vendor users at location level
|
|
341
|
+
wxcli call-recording list-vendor-users-call-recording-1 <location_id>
|
|
342
|
+
|
|
343
|
+
# List call recording jobs
|
|
344
|
+
wxcli call-recording list-call-recording
|
|
345
|
+
|
|
346
|
+
# Get status of a specific recording job
|
|
347
|
+
wxcli call-recording show-call-recording <job_id>
|
|
348
|
+
|
|
349
|
+
# Get errors for a recording job
|
|
350
|
+
wxcli call-recording list-errors <job_id>
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
### 1.6 Key Behaviors
|
|
354
|
+
|
|
355
|
+
- `set_org_vendor()` and `set_location_vendor()` return a **job ID** (string). Use the jobs API to check status if the change cannot be applied immediately (HTTP 200 with jobId vs. 204 for immediate).
|
|
356
|
+
- `update()` (enable/disable recording) is **Cisco partners only**.
|
|
357
|
+
- Storage region is **only applicable when vendor is Webex**; ignored for third-party vendors.
|
|
358
|
+
- `standard_user_only` parameter filters to Webex Calling standard license users only.
|
|
359
|
+
|
|
360
|
+
---
|
|
361
|
+
|
|
362
|
+
## 2. Caller Reputation
|
|
363
|
+
|
|
364
|
+
**SDK module:** `wxc_sdk.telephony.caller_reputation`
|
|
365
|
+
**API class:** `CallerReputationProviderApi` (base: `telephony/config/serviceSettings/callerReputationProvider`)
|
|
366
|
+
|
|
367
|
+
Integrates with external calling reputation providers for spam/fraud call scoring.
|
|
368
|
+
|
|
369
|
+
### 2.1 Data Models
|
|
370
|
+
|
|
371
|
+
#### `ReputationProviderSettings`
|
|
372
|
+
|
|
373
|
+
| Field | Type | Notes |
|
|
374
|
+
|-------|------|-------|
|
|
375
|
+
| `name` | `str` | Provider name |
|
|
376
|
+
| `id` | `str` | Provider ID |
|
|
377
|
+
| `client_id` | `str` | OAuth client ID for integration |
|
|
378
|
+
| `client_secret` | `str` | Write-only; not returned on read |
|
|
379
|
+
| `enabled` | `bool` | Service enabled/disabled |
|
|
380
|
+
| `call_block_score_threshold` | `str` | Score at which calls are blocked |
|
|
381
|
+
| `call_allow_score_threshold` | `str` | Score at which calls are allowed |
|
|
382
|
+
|
|
383
|
+
#### `ReputationProviderState` (Enum)
|
|
384
|
+
|
|
385
|
+
| Value | Meaning |
|
|
386
|
+
|-------|---------|
|
|
387
|
+
| `NOT_CONNECTED` | Not connected |
|
|
388
|
+
| `CONNECTING` | Connection in progress |
|
|
389
|
+
| `CONNECTED` | Connected |
|
|
390
|
+
| `ACTIVE` | Active and operational |
|
|
391
|
+
| `EXPIRED` | Session/token expired |
|
|
392
|
+
| `AUTH_FAILED` | Authentication failed |
|
|
393
|
+
| `PROVIDER_DISABLED` | Provider disabled |
|
|
394
|
+
|
|
395
|
+
#### `ReputationProviderStatus`
|
|
396
|
+
|
|
397
|
+
| Field | Type |
|
|
398
|
+
|-------|------|
|
|
399
|
+
| `id` | `str` |
|
|
400
|
+
| `status` | `ReputationProviderState` |
|
|
401
|
+
|
|
402
|
+
#### `ReputationProviderRegion`
|
|
403
|
+
|
|
404
|
+
| Field | Type | Notes |
|
|
405
|
+
|-------|------|-------|
|
|
406
|
+
| `id` | `str` | |
|
|
407
|
+
| `name` | `str` | |
|
|
408
|
+
| `type` | `str` | e.g., primary, secondary |
|
|
409
|
+
| `visible` | `bool` | |
|
|
410
|
+
| `environment_type` | `str` | e.g., production, staging |
|
|
411
|
+
|
|
412
|
+
#### `CallerReputationProviderProvider`
|
|
413
|
+
|
|
414
|
+
| Field | Type |
|
|
415
|
+
|-------|------|
|
|
416
|
+
| `id` | `str` |
|
|
417
|
+
| `enabled` | `bool` |
|
|
418
|
+
| `name` | `str` |
|
|
419
|
+
| `regions` | `list[ReputationProviderRegion]` |
|
|
420
|
+
|
|
421
|
+
### 2.2 API Methods
|
|
422
|
+
|
|
423
|
+
```python
|
|
424
|
+
class CallerReputationProviderApi:
|
|
425
|
+
|
|
426
|
+
def get(self, organization_id: str = None) -> ReputationProviderSettings
|
|
427
|
+
def update(self, settings: ReputationProviderSettings, organization_id: str = None)
|
|
428
|
+
def unlock(self, rep_id: str, organization_id: str = None)
|
|
429
|
+
def providers(self, organization_id: str = None) -> list[CallerReputationProviderProvider]
|
|
430
|
+
def status(self, organization_id: str = None) -> ReputationProviderStatus
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
### 2.3 Raw HTTP — Caller Reputation
|
|
434
|
+
|
|
435
|
+
```python
|
|
436
|
+
BASE = "https://webexapis.com/v1"
|
|
437
|
+
|
|
438
|
+
# GET — Get caller reputation provider settings
|
|
439
|
+
result = api.session.rest_get(
|
|
440
|
+
f"{BASE}/telephony/config/serviceSettings/callerReputationProvider")
|
|
441
|
+
# Response: {"name": "...", "id": "...", "clientId": "...", "enabled": true,
|
|
442
|
+
# "callBlockScoreThreshold": "80", "callAllowScoreThreshold": "20"}
|
|
443
|
+
# Note: clientSecret is NEVER returned by GET
|
|
444
|
+
|
|
445
|
+
# PUT — Update caller reputation provider settings
|
|
446
|
+
body = {
|
|
447
|
+
"enabled": True,
|
|
448
|
+
"id": "<provider_id>",
|
|
449
|
+
"name": "Provider Name",
|
|
450
|
+
"clientId": "<oauth_client_id>",
|
|
451
|
+
"clientSecret": "<oauth_client_secret>",
|
|
452
|
+
"callBlockScoreThreshold": "80",
|
|
453
|
+
"callAllowScoreThreshold": "20"
|
|
454
|
+
}
|
|
455
|
+
api.session.rest_put(
|
|
456
|
+
f"{BASE}/telephony/config/serviceSettings/callerReputationProvider", json=body)
|
|
457
|
+
|
|
458
|
+
# GET — Get provider status
|
|
459
|
+
result = api.session.rest_get(
|
|
460
|
+
f"{BASE}/telephony/config/serviceSettings/callerReputationProvider/status")
|
|
461
|
+
# Response: {"id": "...", "status": "CONNECTED"}
|
|
462
|
+
|
|
463
|
+
# GET — List available providers
|
|
464
|
+
result = api.session.rest_get(
|
|
465
|
+
f"{BASE}/telephony/config/serviceSettings/callerReputationProvider/providers")
|
|
466
|
+
# Response: {"providers": [{"id": "...", "enabled": true, "name": "...",
|
|
467
|
+
# "regions": [{"id": "...", "name": "...", "type": "primary", "visible": true}]}]}
|
|
468
|
+
|
|
469
|
+
# POST — Unlock a locked provider
|
|
470
|
+
body = {"id": "<provider_id>"}
|
|
471
|
+
api.session.rest_post(
|
|
472
|
+
f"{BASE}/telephony/config/serviceSettings/callerReputationProvider/actions/unlock/invoke",
|
|
473
|
+
json=body)
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
**Gotcha:** This API uses `organizationId` as the query parameter (not `orgId` like most other telephony APIs).
|
|
477
|
+
|
|
478
|
+
**Gotcha:** Score thresholds are strings, not integers.
|
|
479
|
+
<!-- Updated by playbook session 2026-03-18 -->
|
|
480
|
+
|
|
481
|
+
### 2.4 CLI Examples
|
|
482
|
+
|
|
483
|
+
```bash
|
|
484
|
+
# Get caller reputation provider settings
|
|
485
|
+
wxcli caller-reputation show
|
|
486
|
+
|
|
487
|
+
# Get caller reputation provider status
|
|
488
|
+
wxcli caller-reputation show-status
|
|
489
|
+
|
|
490
|
+
# List available caller reputation providers
|
|
491
|
+
wxcli caller-reputation list
|
|
492
|
+
|
|
493
|
+
# Update caller reputation provider settings
|
|
494
|
+
wxcli caller-reputation update \
|
|
495
|
+
--enabled --id <provider_id> --name "Provider Name" \
|
|
496
|
+
--client-id <oauth_client_id> --client-secret <oauth_client_secret> \
|
|
497
|
+
--call-block-score-threshold "80" --call-allow-score-threshold "20"
|
|
498
|
+
|
|
499
|
+
# Unlock a locked caller reputation provider
|
|
500
|
+
wxcli caller-reputation unlock-caller-reputation
|
|
501
|
+
|
|
502
|
+
# Query for a specific org (partner scenario)
|
|
503
|
+
wxcli caller-reputation show --organization-id <org_id>
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
### 2.5 Key Behaviors
|
|
507
|
+
|
|
508
|
+
- **`client_secret` is write-only** -- it is never returned by `get()`. Only usable in `update()`.
|
|
509
|
+
- The `unlock()` method invokes `actions/unlock/invoke` -- use this when the provider is in a locked state (e.g., after auth failure). <!-- UNVERIFIABLE: exact conditions that trigger a locked state are not documented in SDK or OpenAPI spec; would need live API testing -->
|
|
510
|
+
- Note the parameter is `organization_id` (not `org_id`) in this API, differing from most other telephony APIs.
|
|
511
|
+
- Score thresholds are strings, not integers. The OpenAPI spec examples show decimal numeric strings (e.g., `"0.7"`, `"0.3"`), not integer strings.
|
|
512
|
+
|
|
513
|
+
---
|
|
514
|
+
|
|
515
|
+
## 3. Conference Controls
|
|
516
|
+
|
|
517
|
+
**SDK module:** `wxc_sdk.telephony.conference`
|
|
518
|
+
**API class:** `ConferenceControlsApi` (base: `telephony/conference`)
|
|
519
|
+
|
|
520
|
+
Runtime conference call management (not configuration). This is a **call-control** API, not an admin config API.
|
|
521
|
+
|
|
522
|
+
### 3.1 Scopes
|
|
523
|
+
|
|
524
|
+
| Operation | Scope |
|
|
525
|
+
|-----------|-------|
|
|
526
|
+
| GET | `spark:calls_read` |
|
|
527
|
+
| All others | `spark:calls_write` |
|
|
528
|
+
|
|
529
|
+
### 3.2 Data Models
|
|
530
|
+
|
|
531
|
+
#### `ConferenceState` (Enum)
|
|
532
|
+
|
|
533
|
+
| Value | Meaning |
|
|
534
|
+
|-------|---------|
|
|
535
|
+
| `connected` | Host is active participant |
|
|
536
|
+
| `held` | Host has held the conference |
|
|
537
|
+
| `disconnected` | Conference released |
|
|
538
|
+
|
|
539
|
+
#### `ConferenceTypeEnum` (Enum)
|
|
540
|
+
|
|
541
|
+
| Value | Usage |
|
|
542
|
+
|-------|-------|
|
|
543
|
+
| `bargeIn` | Barge-in conference |
|
|
544
|
+
| `silentMonitoring` | Silent monitoring |
|
|
545
|
+
| `coaching` | Coaching session |
|
|
546
|
+
|
|
547
|
+
#### `ConferenceParticipant`
|
|
548
|
+
|
|
549
|
+
| Field | Type | Notes |
|
|
550
|
+
|-------|------|-------|
|
|
551
|
+
| `call_id` | `str` | Call identifier for this participant |
|
|
552
|
+
| `muted` | `bool` | |
|
|
553
|
+
| `deafened` | `bool` | Media not transmitted to participant |
|
|
554
|
+
|
|
555
|
+
#### `ConferenceDetails`
|
|
556
|
+
|
|
557
|
+
| Field | Type | Notes |
|
|
558
|
+
|-------|------|-------|
|
|
559
|
+
| `state` | `ConferenceState` | |
|
|
560
|
+
| `appearance` | `int` | Appearance index (if assigned) |
|
|
561
|
+
| `created` | `datetime` | ISO 8601 start time |
|
|
562
|
+
| `muted` | `bool` | Host muted |
|
|
563
|
+
| `type` | `ConferenceTypeEnum` | Only for non-standard conferences |
|
|
564
|
+
| `participants` | `list[ConferenceParticipant]` | |
|
|
565
|
+
|
|
566
|
+
### 3.3 API Methods
|
|
567
|
+
|
|
568
|
+
```python
|
|
569
|
+
class ConferenceControlsApi:
|
|
570
|
+
|
|
571
|
+
def start_conference(self, call_ids: list[str], line_owner_id: str = None)
|
|
572
|
+
def get_conference_details(self, line_owner_id: str = None) -> ConferenceDetails
|
|
573
|
+
def release_conference(self, line_owner_id: str = None)
|
|
574
|
+
def add_participant(self, call_id: str, line_owner_id: str = None)
|
|
575
|
+
def hold(self, line_owner_id: str = None)
|
|
576
|
+
def resume(self, line_owner_id: str = None)
|
|
577
|
+
def mute(self, call_id: str = None) # host if call_id omitted
|
|
578
|
+
def unmute(self, call_id: str = None) # host if call_id omitted
|
|
579
|
+
def deafen_participant(self, call_id: str)
|
|
580
|
+
def undeafen_participant(self, call_id: str)
|
|
581
|
+
```
|
|
582
|
+
|
|
583
|
+
### 3.4 CLI Examples
|
|
584
|
+
|
|
585
|
+
```bash
|
|
586
|
+
# Get current conference details (requires user-level OAuth token)
|
|
587
|
+
wxcli conference list
|
|
588
|
+
|
|
589
|
+
# Get conference details for a specific line owner
|
|
590
|
+
wxcli conference list --line-owner-id <user_id>
|
|
591
|
+
|
|
592
|
+
# Start a conference by merging two active calls
|
|
593
|
+
wxcli conference create --json-body '{"callIds": ["call_id_1", "call_id_2"]}'
|
|
594
|
+
|
|
595
|
+
# Add a participant to an active conference
|
|
596
|
+
wxcli conference create-add-participant --json-body '{"callId": "call_id_3"}'
|
|
597
|
+
|
|
598
|
+
# Hold / resume the conference
|
|
599
|
+
wxcli conference create-hold
|
|
600
|
+
wxcli conference create-resume
|
|
601
|
+
|
|
602
|
+
# Mute the host
|
|
603
|
+
wxcli conference create-mute
|
|
604
|
+
|
|
605
|
+
# Mute a specific participant
|
|
606
|
+
wxcli conference create-mute --json-body '{"callId": "participant_call_id"}'
|
|
607
|
+
|
|
608
|
+
# Unmute
|
|
609
|
+
wxcli conference create-unmute
|
|
610
|
+
|
|
611
|
+
# Deafen / undeafen a participant
|
|
612
|
+
wxcli conference create-deafen --json-body '{"callId": "participant_call_id"}'
|
|
613
|
+
wxcli conference create-undeafen --json-body '{"callId": "participant_call_id"}'
|
|
614
|
+
|
|
615
|
+
# Release (end) the conference
|
|
616
|
+
wxcli conference delete
|
|
617
|
+
```
|
|
618
|
+
|
|
619
|
+
> **Note:** Conference controls require a **user-level OAuth token** (`spark:calls_write` scope). Admin tokens will not work. See Known Issues in CLAUDE.md.
|
|
620
|
+
|
|
621
|
+
### 3.5 Key Behaviors
|
|
622
|
+
|
|
623
|
+
- **`start_conference()`** requires a minimum of **two call IDs**. Each must identify an existing call between the invoking user and a participant.
|
|
624
|
+
- **`get_conference_details()`** returns an **empty JSON object** if no conference exists.
|
|
625
|
+
- **Mute vs. Deafen**: Muting stops a participant's audio from being transmitted to the conference. Deafening stops the conference audio from being transmitted to the participant. They are independent.
|
|
626
|
+
- **`mute()` / `unmute()`** operate on the host when `call_id` is omitted, or on a specific participant when provided.
|
|
627
|
+
- **`line_owner_id`** is used when invoking the API on behalf of a secondary line owner (user, workspace, or virtual line).
|
|
628
|
+
- For three-way calls (3WC), the Transfer API can be used instead of `release_conference()` to keep participants connected while the host drops.
|
|
629
|
+
|
|
630
|
+
---
|
|
631
|
+
|
|
632
|
+
## 4. Supervisors
|
|
633
|
+
|
|
634
|
+
> For the full Customer Assist setup workflow including supervisors, use the **customer-assist** skill.
|
|
635
|
+
|
|
636
|
+
**SDK module:** `wxc_sdk.telephony.supervisor`
|
|
637
|
+
**API class:** `SupervisorApi` (base: `telephony/config/supervisors`)
|
|
638
|
+
|
|
639
|
+
Supervisors manage call queue agents. They can silently monitor, coach, barge in, or take over calls their agents are handling.
|
|
640
|
+
|
|
641
|
+
### 4.1 Scopes
|
|
642
|
+
|
|
643
|
+
| Operation | Scope |
|
|
644
|
+
|-----------|-------|
|
|
645
|
+
| Read | `spark-admin:telephony_config_read` |
|
|
646
|
+
| Write | `spark-admin:telephony_config_write` |
|
|
647
|
+
|
|
648
|
+
### 4.2 Data Models
|
|
649
|
+
|
|
650
|
+
#### `AgentOrSupervisor`
|
|
651
|
+
Used for both supervisor and agent listings.
|
|
652
|
+
|
|
653
|
+
| Field | Type | Notes |
|
|
654
|
+
|-------|------|-------|
|
|
655
|
+
| `id` | `str` | |
|
|
656
|
+
| `first_name` | `str` | |
|
|
657
|
+
| `last_name` | `str` | |
|
|
658
|
+
| `display_name` | `str` | |
|
|
659
|
+
| `phone_number` | `str` | |
|
|
660
|
+
| `extension` | `str` | |
|
|
661
|
+
| `routing_prefix` | `str` | Location routing prefix |
|
|
662
|
+
| `esn` | `str` | Routing prefix + extension |
|
|
663
|
+
| `type` | `UserType` | Person, workspace, or virtual line |
|
|
664
|
+
| `has_cx_essentials` | `bool` | Has Customer Assist (formerly CX Essentials) license |
|
|
665
|
+
| `agent_count` | `int` | Agents managed (supervisors only) |
|
|
666
|
+
|
|
667
|
+
#### `IdAndAction`
|
|
668
|
+
|
|
669
|
+
| Field | Type | Notes |
|
|
670
|
+
|-------|------|-------|
|
|
671
|
+
| `id` | `str` | Person, workspace, or virtual line ID |
|
|
672
|
+
| `action` | `PatternAction` | `ADD` or `DELETE` |
|
|
673
|
+
|
|
674
|
+
#### `SupervisorAgentStatus`
|
|
675
|
+
|
|
676
|
+
| Field | Type | Notes |
|
|
677
|
+
|-------|------|-------|
|
|
678
|
+
| `id` | `str` | |
|
|
679
|
+
| `status` | `str` | Status result |
|
|
680
|
+
| `message` | `str` | Detail message |
|
|
681
|
+
| `type` | `UserType` | SDK-only field; absent from OpenAPI spec `ListSupervisorAgentStatusObject`. SDK marks as `# TODO: undocumented, issue 202` |
|
|
682
|
+
|
|
683
|
+
### 4.3 API Methods
|
|
684
|
+
|
|
685
|
+
```python
|
|
686
|
+
class SupervisorApi:
|
|
687
|
+
|
|
688
|
+
# --- List / search ---
|
|
689
|
+
def list(self, name: str = None, phone_number: str = None, order: str = None,
|
|
690
|
+
has_cx_essentials: bool = None, org_id: str = None,
|
|
691
|
+
**params) -> Generator[AgentOrSupervisor]
|
|
692
|
+
|
|
693
|
+
def available_supervisors(self, name: str = None, phone_number: str = None, order: str = None,
|
|
694
|
+
has_cx_essentials: bool = None, org_id: str = None,
|
|
695
|
+
**params) -> Generator[AgentOrSupervisor]
|
|
696
|
+
|
|
697
|
+
def available_agents(self, name: str = None, phone_number: str = None, order: str = None,
|
|
698
|
+
has_cx_essentials: bool = None, org_id: str = None,
|
|
699
|
+
**params) -> Generator[AgentOrSupervisor]
|
|
700
|
+
|
|
701
|
+
# --- CRUD ---
|
|
702
|
+
def create(self, id: str, agents: list[str], has_cx_essentials: bool = None, org_id: str = None)
|
|
703
|
+
def delete(self, supervisor_id: str, org_id: str = None)
|
|
704
|
+
def delete_bulk(self, supervisors_ids: list[str], delete_all: bool = None, org_id: str = None)
|
|
705
|
+
|
|
706
|
+
# --- Details and agent assignment ---
|
|
707
|
+
def details(self, supervisor_id: str, name: str = None, phone_number: str = None,
|
|
708
|
+
order: str = None, has_cx_essentials: bool = None,
|
|
709
|
+
org_id: str = None, **additional_params) -> Generator[AgentOrSupervisor]
|
|
710
|
+
|
|
711
|
+
def assign_unassign_agents(self, supervisor_id: str, agents: list[IdAndAction],
|
|
712
|
+
has_cx_essentials: bool = None,
|
|
713
|
+
org_id: str = None) -> Optional[list[SupervisorAgentStatus]]
|
|
714
|
+
```
|
|
715
|
+
|
|
716
|
+
### 4.4 CLI Examples
|
|
717
|
+
|
|
718
|
+
Supervisor commands are under the `wxcli call-queue` group. **For Customer Assist supervisors, always include `--has-cx-essentials true`.**
|
|
719
|
+
|
|
720
|
+
```bash
|
|
721
|
+
# List all Customer Assist supervisors
|
|
722
|
+
wxcli call-queue list-supervisors --has-cx-essentials true
|
|
723
|
+
|
|
724
|
+
# List available supervisors (not yet assigned)
|
|
725
|
+
wxcli call-queue list-available-supervisors --has-cx-essentials true
|
|
726
|
+
|
|
727
|
+
# List available agents for supervisor assignment
|
|
728
|
+
wxcli call-queue list-available-agents-supervisors --has-cx-essentials true
|
|
729
|
+
|
|
730
|
+
# Create a supervisor with agents
|
|
731
|
+
wxcli call-queue create-supervisors --has-cx-essentials true \
|
|
732
|
+
--id SUPERVISOR_PERSON_ID --json-body '{"agents": [{"id": "AGENT_ID"}]}'
|
|
733
|
+
|
|
734
|
+
# Show supervisor's assigned agents
|
|
735
|
+
wxcli call-queue show-supervisors SUPERVISOR_ID --has-cx-essentials true -o json
|
|
736
|
+
|
|
737
|
+
# Update supervisor's agents (incremental add/remove)
|
|
738
|
+
wxcli call-queue update-supervisors SUPERVISOR_ID --has-cx-essentials true \
|
|
739
|
+
--json-body '{"agents": [{"id": "AGENT_ID", "action": "ADD"}]}'
|
|
740
|
+
|
|
741
|
+
# Delete a specific supervisor
|
|
742
|
+
wxcli call-queue delete-supervisors-config-1 SUPERVISOR_ID --has-cx-essentials true --force
|
|
743
|
+
|
|
744
|
+
# Delete supervisors in bulk
|
|
745
|
+
wxcli call-queue delete-supervisors-config --has-cx-essentials true --force
|
|
746
|
+
|
|
747
|
+
# RECOMMENDED: Remove supervisor by removing all agents (more reliable)
|
|
748
|
+
wxcli call-queue update-supervisors SUPERVISOR_ID --has-cx-essentials true \
|
|
749
|
+
--json-body '{"agents": [{"id": "AGENT_ID", "action": "DELETE"}]}'
|
|
750
|
+
# When last agent is removed, supervisor is auto-deleted
|
|
751
|
+
```
|
|
752
|
+
|
|
753
|
+
> **WARNING:** `delete-supervisors-config --force` without specifying IDs may remove **all supervisors in the org**. Always confirm scope before executing.
|
|
754
|
+
|
|
755
|
+
> **GOTCHA:** `delete-supervisors-config-1` returns 204 but the Customer Assist supervisor may persist. The reliable method is to remove all agents via `update-supervisors` with `action: DELETE` — when the last agent is removed, the supervisor is automatically deleted.
|
|
756
|
+
|
|
757
|
+
### 4.5 Key Behaviors
|
|
758
|
+
|
|
759
|
+
- **A supervisor must have at least one agent** when created via `create()`.
|
|
760
|
+
- **`create()` takes agent IDs as a flat `list[str]`**, not `IdAndAction` objects. The SDK wraps them as `[{'id': agent_id}]` internally.
|
|
761
|
+
- **`assign_unassign_agents()`** uses `IdAndAction` with `PatternAction.ADD` or `PatternAction.DELETE` to add/remove agents in a single call. Returns `None` if all succeed, or a list of `SupervisorAgentStatus` with per-agent error details.
|
|
762
|
+
- **`delete_bulk()`** has a `delete_all` parameter. When set to `True`, the `supervisors_ids` array is ignored and **all supervisors in the org are removed**. Use with extreme caution.
|
|
763
|
+
- **Customer Assist vs. CX Basic**: The `has_cx_essentials` parameter gates which license tier you are querying/modifying. When `True`, returns/operates on Customer Assist supervisors only. When omitted or `False`, operates on CX Basic.
|
|
764
|
+
- **`details()`** returns a generator of the supervisor's assigned **agents** (not the supervisor's own details). The item key is `agents`.
|
|
765
|
+
|
|
766
|
+
---
|
|
767
|
+
|
|
768
|
+
## 5. Guest Calling (Click-to-Call)
|
|
769
|
+
|
|
770
|
+
**SDK module:** `wxc_sdk.telephony.guest_calling`
|
|
771
|
+
**API class:** `GuestCallingApi` (base: `telephony/config/guestCalling`)
|
|
772
|
+
|
|
773
|
+
Click-to-call allows external (guest) callers to reach internal destinations. Org-level setting.
|
|
774
|
+
|
|
775
|
+
### 5.1 Scopes
|
|
776
|
+
|
|
777
|
+
| Operation | Scope |
|
|
778
|
+
|-----------|-------|
|
|
779
|
+
| Read | `spark-admin:telephony_config_read` |
|
|
780
|
+
| Write | `spark-admin:telephony_config_write` |
|
|
781
|
+
|
|
782
|
+
### 5.2 Data Models
|
|
783
|
+
|
|
784
|
+
#### `GuestCallingSettings`
|
|
785
|
+
|
|
786
|
+
| Field | Type | Notes |
|
|
787
|
+
|-------|------|-------|
|
|
788
|
+
| `enabled` | `bool` | Click-to-call enabled |
|
|
789
|
+
| `privacy_enabled` | `bool` | Privacy mode |
|
|
790
|
+
| `video_enabled` | `bool` | SDK-only field with no docstring; absent from all OpenAPI specs. May be undocumented or deprecated |
|
|
791
|
+
|
|
792
|
+
#### `DestinationMember`
|
|
793
|
+
|
|
794
|
+
| Field | Type | Notes |
|
|
795
|
+
|-------|------|-------|
|
|
796
|
+
| `id` | `str` | |
|
|
797
|
+
| `first_name` | `str` | |
|
|
798
|
+
| `last_name` | `str` | |
|
|
799
|
+
| `phone_number` | `str` | |
|
|
800
|
+
| `extension` | `str` | |
|
|
801
|
+
| `routing_prefix` | `str` | |
|
|
802
|
+
| `esn` | `str` | |
|
|
803
|
+
| `type` | `OwnerType` | |
|
|
804
|
+
| `location` | `IdAndName` | |
|
|
805
|
+
|
|
806
|
+
### 5.3 API Methods
|
|
807
|
+
|
|
808
|
+
```python
|
|
809
|
+
class GuestCallingApi:
|
|
810
|
+
|
|
811
|
+
def read(self, org_id: str = None) -> GuestCallingSettings
|
|
812
|
+
def update(self, enabled: bool, privacy_enabled: bool,
|
|
813
|
+
destination_members: list[str], org_id: str = None)
|
|
814
|
+
def members(self, member_name: str = None, phone_number: str = None,
|
|
815
|
+
extension: str = None, org_id: str = None,
|
|
816
|
+
**params) -> Generator[DestinationMember]
|
|
817
|
+
def available_members(self, member_name: str = None, phone_number: str = None,
|
|
818
|
+
extension: str = None, org_id: str = None,
|
|
819
|
+
**params) -> Generator[DestinationMember]
|
|
820
|
+
```
|
|
821
|
+
|
|
822
|
+
### 5.4 CLI Examples
|
|
823
|
+
|
|
824
|
+
There is no dedicated `wxcli` guest-calling (click-to-call) command group. Use the SDK methods or Raw HTTP calls. The `guest-management` group covers a different feature (guest user creation), not click-to-call destinations.
|
|
825
|
+
|
|
826
|
+
### 5.5 Key Behaviors
|
|
827
|
+
|
|
828
|
+
- **Supported destination types**: Auto Attendant, Call Queue, Hunt Group, and Virtual Line. Not individual users.
|
|
829
|
+
- **`update()` takes destination member IDs** as a flat `list[str]`, not full `DestinationMember` objects.
|
|
830
|
+
- **`members()`** returns currently assigned click-to-call destinations.
|
|
831
|
+
- **`available_members()`** returns destinations that can be added but are not yet assigned.
|
|
832
|
+
- All search parameters (`member_name`, `phone_number`, `extension`) use **contains** matching.
|
|
833
|
+
|
|
834
|
+
---
|
|
835
|
+
|
|
836
|
+
## 6. Operating Modes
|
|
837
|
+
|
|
838
|
+
**SDK module:** `wxc_sdk.telephony.operating_modes`
|
|
839
|
+
**API class:** `OperatingModesApi` (base: `telephony/config`)
|
|
840
|
+
|
|
841
|
+
Operating modes define time-based call routing rules (business hours, after hours, holidays, etc.) used by Auto Attendants, Call Queues, and Hunt Groups via mode-based forwarding.
|
|
842
|
+
|
|
843
|
+
### 6.1 Scopes
|
|
844
|
+
|
|
845
|
+
| Operation | Scope |
|
|
846
|
+
|-----------|-------|
|
|
847
|
+
| Read | `spark-admin:telephony_config_read` |
|
|
848
|
+
| Write | `spark-admin:telephony_config_write` |
|
|
849
|
+
|
|
850
|
+
### 6.2 Data Models
|
|
851
|
+
|
|
852
|
+
#### `OperatingModeSchedule` (Enum)
|
|
853
|
+
|
|
854
|
+
| Value | Meaning |
|
|
855
|
+
|-------|---------|
|
|
856
|
+
| `SAME_HOURS_DAILY` | Same schedule Mon-Fri and Sat-Sun |
|
|
857
|
+
| `DIFFERENT_HOURS_DAILY` | Per-day schedule |
|
|
858
|
+
| `HOLIDAY` | Holiday-based with recurrence |
|
|
859
|
+
| `NONE` | No schedule defined |
|
|
860
|
+
|
|
861
|
+
#### `DaySchedule`
|
|
862
|
+
|
|
863
|
+
| Field | Type | Notes |
|
|
864
|
+
|-------|------|-------|
|
|
865
|
+
| `enabled` | `bool` | Schedule active for this day/group |
|
|
866
|
+
| `all_day_enabled` | `bool` | Active entire day |
|
|
867
|
+
| `start_time` | `time` | HH:MM format |
|
|
868
|
+
| `end_time` | `time` | HH:MM format |
|
|
869
|
+
|
|
870
|
+
#### `SameHoursDaily`
|
|
871
|
+
|
|
872
|
+
| Field | Type |
|
|
873
|
+
|-------|------|
|
|
874
|
+
| `monday_to_friday` | `DaySchedule` |
|
|
875
|
+
| `saturday_to_sunday` | `DaySchedule` |
|
|
876
|
+
|
|
877
|
+
#### `DifferentHoursDaily`
|
|
878
|
+
Individual `DaySchedule` fields for: `sunday`, `monday`, `tuesday`, `wednesday`, `thursday`, `friday`, `saturday`.
|
|
879
|
+
|
|
880
|
+
#### `OperatingModeHoliday`
|
|
881
|
+
|
|
882
|
+
| Field | Type | Notes |
|
|
883
|
+
|-------|------|-------|
|
|
884
|
+
| `id` | `str` | |
|
|
885
|
+
| `name` | `str` | |
|
|
886
|
+
| `all_day_enabled` | `bool` | |
|
|
887
|
+
| `start_date` | `date` | YYYY-MM-DD format |
|
|
888
|
+
| `end_date` | `date` | |
|
|
889
|
+
| `start_time` | `time` | Required if `all_day_enabled` is false |
|
|
890
|
+
| `end_time` | `time` | Required if `all_day_enabled` is false |
|
|
891
|
+
| `recurrence` | `OperatingModeRecurrence` | |
|
|
892
|
+
|
|
893
|
+
#### `OperatingModeRecurrence`
|
|
894
|
+
|
|
895
|
+
| Field | Type |
|
|
896
|
+
|-------|------|
|
|
897
|
+
| `recur_yearly_by_date` | `OperatingModeRecurYearlyByDate` |
|
|
898
|
+
| `recur_yearly_by_day` | `OperatingModeRecurYearlyByDay` |
|
|
899
|
+
|
|
900
|
+
Two recurrence patterns: by date (day of month + month) or by day (day + week + month, e.g., "first Monday of September").
|
|
901
|
+
|
|
902
|
+
#### `OperatingMode`
|
|
903
|
+
|
|
904
|
+
| Field | Type | Notes |
|
|
905
|
+
|-------|------|-------|
|
|
906
|
+
| `id` | `str` | |
|
|
907
|
+
| `name` | `str` | |
|
|
908
|
+
| `type` | `OperatingModeSchedule` | |
|
|
909
|
+
| `level` | `ScheduleLevel` | Org or location |
|
|
910
|
+
| `location` | `IdAndName` | Required if level is LOCATION |
|
|
911
|
+
| `same_hours_daily` | `SameHoursDaily` | Present if type is `SAME_HOURS_DAILY` |
|
|
912
|
+
| `different_hours_daily` | `DifferentHoursDaily` | Present if type is `DIFFERENT_HOURS_DAILY` |
|
|
913
|
+
| `holidays` | `list[OperatingModeHoliday]` | Present if type is `HOLIDAY` |
|
|
914
|
+
| `call_forwarding` | `CallForwardingCommon` | Forwarding settings for this mode |
|
|
915
|
+
|
|
916
|
+
### 6.3 API Methods
|
|
917
|
+
|
|
918
|
+
```python
|
|
919
|
+
class OperatingModesApi:
|
|
920
|
+
|
|
921
|
+
# --- CRUD ---
|
|
922
|
+
def list(self, limit_to_location_id: str = None, name: str = None,
|
|
923
|
+
limit_to_org_level_enabled: bool = None, order: str = None,
|
|
924
|
+
org_id: str = None, **params) -> Generator[OperatingMode]
|
|
925
|
+
|
|
926
|
+
def details(self, mode_id: str, org_id: str = None) -> OperatingMode
|
|
927
|
+
def create(self, settings: OperatingMode, org_id: str = None) -> str # returns mode ID
|
|
928
|
+
def update(self, mode_id: str, settings: OperatingMode, org_id: str = None)
|
|
929
|
+
def delete(self, mode_id: str, org_id: str = None)
|
|
930
|
+
|
|
931
|
+
# --- Holiday management ---
|
|
932
|
+
def holiday_details(self, mode_id: str, holiday_id: str, org_id: str = None) -> OperatingModeHoliday
|
|
933
|
+
def holiday_create(self, mode_id: str, settings: OperatingModeHoliday, org_id: str = None) -> str # returns holiday ID
|
|
934
|
+
# Verified via CLI implementation 2026-03-17: holiday_create requires start_date and end_date (not just date), plus all_day_enabled. Only HOLIDAY type operating modes accept holiday events.
|
|
935
|
+
def holiday_update(self, mode_id: str, holiday_id: str, settings: OperatingModeHoliday, org_id: str = None)
|
|
936
|
+
def holiday_delete(self, mode_id: str, holiday_id: str = None, org_id: str = None)
|
|
937
|
+
|
|
938
|
+
# --- Availability queries ---
|
|
939
|
+
def available_operating_modes(self, location_id: str, org_id: str = None) -> list[IdAndName]
|
|
940
|
+
def call_forward_available_phone_numbers(self, location_id: str, phone_number: list[str] = None,
|
|
941
|
+
owner_name: str = None, extension: str = None,
|
|
942
|
+
org_id: str = None, **params) -> Generator[AvailableNumber]
|
|
943
|
+
```
|
|
944
|
+
|
|
945
|
+
### 6.4 Raw HTTP — Operating Modes
|
|
946
|
+
|
|
947
|
+
```python
|
|
948
|
+
BASE = "https://webexapis.com/v1"
|
|
949
|
+
|
|
950
|
+
# --- Operating Mode CRUD ---
|
|
951
|
+
|
|
952
|
+
# GET — List operating modes (paginated)
|
|
953
|
+
result = api.session.rest_get(f"{BASE}/telephony/config/operatingModes",
|
|
954
|
+
params={"max": 1000, "limitToLocationId": loc_id})
|
|
955
|
+
# Response: {"operatingModes": [{"id": "...", "name": "...", "type": "SAME_HOURS_DAILY",
|
|
956
|
+
# "level": "ORGANIZATION"}]}
|
|
957
|
+
# Optional params: name, limitToOrgLevelEnabled, order (asc/desc by name)
|
|
958
|
+
|
|
959
|
+
# GET — Get operating mode details
|
|
960
|
+
result = api.session.rest_get(f"{BASE}/telephony/config/operatingModes/{mode_id}")
|
|
961
|
+
# Response includes full schedule data (sameHoursDaily, differentHoursDaily, or holidays)
|
|
962
|
+
# plus callForwarding settings
|
|
963
|
+
|
|
964
|
+
# POST — Create an operating mode
|
|
965
|
+
body = {
|
|
966
|
+
"name": "Business Hours",
|
|
967
|
+
"type": "SAME_HOURS_DAILY",
|
|
968
|
+
"level": "ORGANIZATION",
|
|
969
|
+
"sameHoursDaily": {
|
|
970
|
+
"mondayToFriday": {
|
|
971
|
+
"enabled": True,
|
|
972
|
+
"allDayEnabled": False,
|
|
973
|
+
"startTime": "09:00",
|
|
974
|
+
"endTime": "17:00"
|
|
975
|
+
},
|
|
976
|
+
"saturdayToSunday": {
|
|
977
|
+
"enabled": False
|
|
978
|
+
}
|
|
979
|
+
}
|
|
980
|
+
}
|
|
981
|
+
result = api.session.rest_post(f"{BASE}/telephony/config/operatingModes/", json=body)
|
|
982
|
+
# Returns: {"id": "<mode_id>"}
|
|
983
|
+
|
|
984
|
+
# For location-scoped:
|
|
985
|
+
body = {
|
|
986
|
+
"name": "Branch Office Hours",
|
|
987
|
+
"type": "DIFFERENT_HOURS_DAILY",
|
|
988
|
+
"level": "LOCATION",
|
|
989
|
+
"locationId": "<loc_id>",
|
|
990
|
+
"differentHoursDaily": {
|
|
991
|
+
"monday": {"enabled": True, "startTime": "08:00", "endTime": "18:00"},
|
|
992
|
+
"tuesday": {"enabled": True, "startTime": "08:00", "endTime": "18:00"},
|
|
993
|
+
"wednesday": {"enabled": True, "startTime": "08:00", "endTime": "18:00"},
|
|
994
|
+
"thursday": {"enabled": True, "startTime": "08:00", "endTime": "18:00"},
|
|
995
|
+
"friday": {"enabled": True, "startTime": "08:00", "endTime": "16:00"},
|
|
996
|
+
"saturday": {"enabled": False},
|
|
997
|
+
"sunday": {"enabled": False}
|
|
998
|
+
}
|
|
999
|
+
}
|
|
1000
|
+
result = api.session.rest_post(f"{BASE}/telephony/config/operatingModes/", json=body)
|
|
1001
|
+
|
|
1002
|
+
# PUT — Update an operating mode
|
|
1003
|
+
body = {"name": "Updated Business Hours"}
|
|
1004
|
+
api.session.rest_put(f"{BASE}/telephony/config/operatingModes/{mode_id}", json=body)
|
|
1005
|
+
|
|
1006
|
+
# DELETE — Delete an operating mode
|
|
1007
|
+
api.session.rest_delete(f"{BASE}/telephony/config/operatingModes/{mode_id}")
|
|
1008
|
+
|
|
1009
|
+
# --- Holiday management (only for HOLIDAY type operating modes) ---
|
|
1010
|
+
|
|
1011
|
+
# GET — Get holiday details
|
|
1012
|
+
result = api.session.rest_get(
|
|
1013
|
+
f"{BASE}/telephony/config/operatingModes/{mode_id}/holidays/{holiday_id}")
|
|
1014
|
+
|
|
1015
|
+
# POST — Create a holiday
|
|
1016
|
+
body = {
|
|
1017
|
+
"name": "Independence Day",
|
|
1018
|
+
"allDayEnabled": True,
|
|
1019
|
+
"startDate": "2026-07-04",
|
|
1020
|
+
"endDate": "2026-07-04"
|
|
1021
|
+
}
|
|
1022
|
+
result = api.session.rest_post(
|
|
1023
|
+
f"{BASE}/telephony/config/operatingModes/{mode_id}/holidays", json=body)
|
|
1024
|
+
# Returns: {"id": "<holiday_id>"}
|
|
1025
|
+
|
|
1026
|
+
# POST — Create holiday with yearly recurrence
|
|
1027
|
+
body = {
|
|
1028
|
+
"name": "Christmas",
|
|
1029
|
+
"allDayEnabled": True,
|
|
1030
|
+
"startDate": "2026-12-25",
|
|
1031
|
+
"endDate": "2026-12-25",
|
|
1032
|
+
"recurrence": {
|
|
1033
|
+
"recurYearlyByDate": {"dayOfMonth": 25, "month": "DECEMBER"}
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
result = api.session.rest_post(
|
|
1037
|
+
f"{BASE}/telephony/config/operatingModes/{mode_id}/holidays", json=body)
|
|
1038
|
+
|
|
1039
|
+
# PUT — Update a holiday
|
|
1040
|
+
body = {"name": "Christmas Day", "allDayEnabled": True,
|
|
1041
|
+
"startDate": "2026-12-25", "endDate": "2026-12-25"}
|
|
1042
|
+
api.session.rest_put(
|
|
1043
|
+
f"{BASE}/telephony/config/operatingModes/{mode_id}/holidays/{holiday_id}", json=body)
|
|
1044
|
+
|
|
1045
|
+
# DELETE — Delete a holiday
|
|
1046
|
+
api.session.rest_delete(
|
|
1047
|
+
f"{BASE}/telephony/config/operatingModes/{mode_id}/holidays/{holiday_id}")
|
|
1048
|
+
|
|
1049
|
+
# --- Availability queries ---
|
|
1050
|
+
|
|
1051
|
+
# GET — Available operating modes for a location (up to 200: location + org combined)
|
|
1052
|
+
result = api.session.rest_get(
|
|
1053
|
+
f"{BASE}/telephony/config/locations/{loc_id}/operatingModes/availableOperatingModes")
|
|
1054
|
+
# Response: {"availableOperatingModes": [{"id": "...", "name": "..."}]}
|
|
1055
|
+
|
|
1056
|
+
# GET — Available phone numbers for call forwarding in operating modes
|
|
1057
|
+
result = api.session.rest_get(
|
|
1058
|
+
f"{BASE}/telephony/config/locations/{loc_id}/operatingModes/callForwarding/availableNumbers",
|
|
1059
|
+
params={"max": 1000})
|
|
1060
|
+
# Response: {"availableNumbers": [{"phoneNumber": "+1...", "ownerName": "...", "extension": "..."}]}
|
|
1061
|
+
```
|
|
1062
|
+
|
|
1063
|
+
**Gotcha:** Create requires `level` set to `ORGANIZATION` or `LOCATION`. For `LOCATION`, you must also include `locationId` in the body. The `type` field must use the enum value directly (e.g., `SAME_HOURS_DAILY`, `DIFFERENT_HOURS_DAILY`, `HOLIDAY`).
|
|
1064
|
+
|
|
1065
|
+
**Gotcha:** For `SAME_HOURS_DAILY` type, you must provide actual schedule data in `sameHoursDaily` -- the API rejects a create with no schedule data.
|
|
1066
|
+
|
|
1067
|
+
**Gotcha:** Holidays can only be added to operating modes with `type: HOLIDAY`. The `holiday_create` endpoint requires `startDate`, `endDate`, and `allDayEnabled` at minimum.
|
|
1068
|
+
|
|
1069
|
+
### 6.5 CLI Examples
|
|
1070
|
+
|
|
1071
|
+
```bash
|
|
1072
|
+
# List all operating modes
|
|
1073
|
+
wxcli operating-modes list
|
|
1074
|
+
|
|
1075
|
+
# List operating modes for a specific location
|
|
1076
|
+
wxcli operating-modes list --limit-to-location-id <location_id>
|
|
1077
|
+
|
|
1078
|
+
# List org-level operating modes only
|
|
1079
|
+
wxcli operating-modes list --limit-to-org-level-enabled true
|
|
1080
|
+
|
|
1081
|
+
# Search operating modes by name
|
|
1082
|
+
wxcli operating-modes list --name "Business Hours"
|
|
1083
|
+
|
|
1084
|
+
# Get details for an operating mode
|
|
1085
|
+
wxcli operating-modes show <mode_id>
|
|
1086
|
+
|
|
1087
|
+
# Create an operating mode (requires --json-body for schedule data)
|
|
1088
|
+
wxcli operating-modes create --name "Business Hours" --json-body '{
|
|
1089
|
+
"type": "SAME_HOURS_DAILY",
|
|
1090
|
+
"level": "ORGANIZATION",
|
|
1091
|
+
"sameHoursDaily": {
|
|
1092
|
+
"mondayToFriday": {"enabled": true, "startTime": "09:00", "endTime": "17:00"},
|
|
1093
|
+
"saturdayToSunday": {"enabled": false}
|
|
1094
|
+
}
|
|
1095
|
+
}'
|
|
1096
|
+
|
|
1097
|
+
# Create a location-scoped operating mode
|
|
1098
|
+
wxcli operating-modes create --name "Branch Hours" \
|
|
1099
|
+
--location-id <location_id> --json-body '{
|
|
1100
|
+
"type": "DIFFERENT_HOURS_DAILY",
|
|
1101
|
+
"level": "LOCATION",
|
|
1102
|
+
"differentHoursDaily": {
|
|
1103
|
+
"monday": {"enabled": true, "startTime": "08:00", "endTime": "18:00"},
|
|
1104
|
+
"tuesday": {"enabled": true, "startTime": "08:00", "endTime": "18:00"},
|
|
1105
|
+
"wednesday": {"enabled": true, "startTime": "08:00", "endTime": "18:00"},
|
|
1106
|
+
"thursday": {"enabled": true, "startTime": "08:00", "endTime": "18:00"},
|
|
1107
|
+
"friday": {"enabled": true, "startTime": "08:00", "endTime": "16:00"},
|
|
1108
|
+
"saturday": {"enabled": false},
|
|
1109
|
+
"sunday": {"enabled": false}
|
|
1110
|
+
}
|
|
1111
|
+
}'
|
|
1112
|
+
|
|
1113
|
+
# Update an operating mode
|
|
1114
|
+
wxcli operating-modes update <mode_id> --json-body '{"name": "Updated Business Hours"}'
|
|
1115
|
+
|
|
1116
|
+
# Delete an operating mode
|
|
1117
|
+
wxcli operating-modes delete <mode_id>
|
|
1118
|
+
|
|
1119
|
+
# Create a holiday on a HOLIDAY-type operating mode
|
|
1120
|
+
wxcli operating-modes create-holidays <mode_id> \
|
|
1121
|
+
--name "Independence Day" --all-day-enabled \
|
|
1122
|
+
--start-date "2026-07-04" --end-date "2026-07-04"
|
|
1123
|
+
|
|
1124
|
+
# Get holiday details
|
|
1125
|
+
wxcli operating-modes show-holidays <mode_id> <holiday_id>
|
|
1126
|
+
|
|
1127
|
+
# Delete a holiday
|
|
1128
|
+
wxcli operating-modes delete-holidays <mode_id> <holiday_id>
|
|
1129
|
+
|
|
1130
|
+
# List available operating modes for a location
|
|
1131
|
+
wxcli operating-modes list-available-operating-modes <location_id>
|
|
1132
|
+
|
|
1133
|
+
# List available phone numbers for call forwarding in operating modes
|
|
1134
|
+
wxcli operating-modes list-available-numbers <location_id>
|
|
1135
|
+
```
|
|
1136
|
+
|
|
1137
|
+
### 6.6 Key Behaviors
|
|
1138
|
+
|
|
1139
|
+
- **Max 100 operating modes per location** and 100 per org. `available_operating_modes()` returns up to 200 (location + org combined).
|
|
1140
|
+
- **Max 150 holidays per operating mode.**
|
|
1141
|
+
- The `create()` method requires at least `name`, `type`, and `level` on the `OperatingMode` object. If `level` is LOCATION, `location.id` must be set.
|
|
1142
|
+
- On `create()`, the SDK internally converts `location` to `locationId` and strips `id` from holidays. On `update()`, it additionally strips `type` and `level` (immutable after creation).
|
|
1143
|
+
- `call_forward_available_phone_numbers()` lists PSTN numbers available as forwarding destinations for operating modes at a given location.
|
|
1144
|
+
- The `list()` result is sorted ascending by operating mode name.
|
|
1145
|
+
|
|
1146
|
+
---
|
|
1147
|
+
|
|
1148
|
+
## 7. Hot Desking Sign-in via Voice Portal
|
|
1149
|
+
|
|
1150
|
+
**SDK module:** `wxc_sdk.telephony.hotdesking_voiceportal`
|
|
1151
|
+
**API class:** `HotDeskingSigninViaVoicePortalApi` (base: `telephony/config`)
|
|
1152
|
+
|
|
1153
|
+
Hot desking allows users to sign in to a shared phone via the voice portal and make calls using their own phone number.
|
|
1154
|
+
|
|
1155
|
+
### 7.1 Scopes
|
|
1156
|
+
|
|
1157
|
+
| Operation | Scope |
|
|
1158
|
+
|-----------|-------|
|
|
1159
|
+
| Read | `spark-admin:telephony_config_read` |
|
|
1160
|
+
| Write | `spark-admin:telephony_config_write` |
|
|
1161
|
+
|
|
1162
|
+
### 7.2 Data Models
|
|
1163
|
+
|
|
1164
|
+
#### `HotDeskingVoicePortalSetting`
|
|
1165
|
+
|
|
1166
|
+
| Field | Type | Notes |
|
|
1167
|
+
|-------|------|-------|
|
|
1168
|
+
| `enabled` | `bool` | JSON alias: `voicePortalHotDeskSignInEnabled` |
|
|
1169
|
+
|
|
1170
|
+
Single boolean -- enables or disables hot desking sign-in via voice portal.
|
|
1171
|
+
|
|
1172
|
+
### 7.3 API Methods
|
|
1173
|
+
|
|
1174
|
+
```python
|
|
1175
|
+
class HotDeskingSigninViaVoicePortalApi:
|
|
1176
|
+
|
|
1177
|
+
# --- Location level ---
|
|
1178
|
+
def location_get(self, location_id: str, org_id: str = None) -> HotDeskingVoicePortalSetting
|
|
1179
|
+
def location_update(self, location_id: str, setting: HotDeskingVoicePortalSetting, org_id: str = None)
|
|
1180
|
+
|
|
1181
|
+
# --- User level ---
|
|
1182
|
+
def user_get(self, person_id: str, org_id: str = None) -> HotDeskingVoicePortalSetting
|
|
1183
|
+
def user_update(self, person_id: str, setting: HotDeskingVoicePortalSetting, org_id: str = None)
|
|
1184
|
+
```
|
|
1185
|
+
|
|
1186
|
+
### 7.4 CLI: `hot-desking-portal`
|
|
1187
|
+
|
|
1188
|
+
| Command | Description |
|
|
1189
|
+
|---------|-------------|
|
|
1190
|
+
| `hot-desking-portal show <location_id>` | Get voice portal hot desking settings for a location |
|
|
1191
|
+
| `hot-desking-portal update <location_id>` | Update voice portal hot desking settings for a location |
|
|
1192
|
+
| `hot-desking-portal show-guest <person_id>` | Get voice portal hot desking settings for a user |
|
|
1193
|
+
| `hot-desking-portal update-guest <person_id>` | Update voice portal hot desking settings for a user |
|
|
1194
|
+
|
|
1195
|
+
```bash
|
|
1196
|
+
# Get hot desking voice portal settings for a location
|
|
1197
|
+
wxcli hot-desking-portal show <location_id>
|
|
1198
|
+
|
|
1199
|
+
# Enable hot desking sign-in via voice portal for a location
|
|
1200
|
+
wxcli hot-desking-portal update <location_id> --voice-portal-hot-desk-sign-in-enabled
|
|
1201
|
+
|
|
1202
|
+
# Disable hot desking sign-in via voice portal for a location
|
|
1203
|
+
wxcli hot-desking-portal update <location_id> --no-voice-portal-hot-desk-sign-in-enabled
|
|
1204
|
+
|
|
1205
|
+
# Get hot desking guest settings for a specific user
|
|
1206
|
+
wxcli hot-desking-portal show-guest <person_id>
|
|
1207
|
+
|
|
1208
|
+
# Enable a user as a hot desking guest
|
|
1209
|
+
wxcli hot-desking-portal update-guest <person_id> --voice-portal-hot-desk-sign-in-enabled
|
|
1210
|
+
|
|
1211
|
+
# Disable a user as a hot desking guest
|
|
1212
|
+
wxcli hot-desking-portal update-guest <person_id> --no-voice-portal-hot-desk-sign-in-enabled
|
|
1213
|
+
```
|
|
1214
|
+
|
|
1215
|
+
### 7.5 Key Behaviors
|
|
1216
|
+
|
|
1217
|
+
- Location endpoint: `locations/{location_id}/features/hotDesking`
|
|
1218
|
+
- User endpoint: `people/{person_id}/features/hotDesking/guest`
|
|
1219
|
+
- This is a simple enable/disable toggle at both location and per-user levels.
|
|
1220
|
+
- The user-level setting controls whether a specific user can act as a hot desking guest.
|
|
1221
|
+
|
|
1222
|
+
---
|
|
1223
|
+
|
|
1224
|
+
## 8. Forwarding (Shared Patterns)
|
|
1225
|
+
|
|
1226
|
+
**SDK module:** `wxc_sdk.telephony.forwarding`
|
|
1227
|
+
**API class:** `ForwardingApi` (base: dynamic per feature)
|
|
1228
|
+
|
|
1229
|
+
Shared forwarding settings and selective rules used by **Call Queues**, **Hunt Groups**, and **Auto Attendants**. The `ForwardingApi` is instantiated with a `FeatureSelector` that determines which feature type it operates on.
|
|
1230
|
+
|
|
1231
|
+
### 8.1 Feature Selectors
|
|
1232
|
+
|
|
1233
|
+
```python
|
|
1234
|
+
class FeatureSelector(str, Enum):
|
|
1235
|
+
queues = 'queues'
|
|
1236
|
+
huntgroups = 'huntGroups'
|
|
1237
|
+
auto_attendants = 'autoAttendants'
|
|
1238
|
+
```
|
|
1239
|
+
|
|
1240
|
+
The API endpoint is constructed as:
|
|
1241
|
+
```
|
|
1242
|
+
telephony/config/locations/{location_id}/{feature}/{feature_id}/callForwarding[/{path}]
|
|
1243
|
+
```
|
|
1244
|
+
|
|
1245
|
+
### 8.2 Data Models
|
|
1246
|
+
|
|
1247
|
+
#### `CallForwarding`
|
|
1248
|
+
Top-level forwarding configuration for a feature.
|
|
1249
|
+
|
|
1250
|
+
| Field | Type | Notes |
|
|
1251
|
+
|-------|------|-------|
|
|
1252
|
+
| `always` | `ForwardingSetting` | Forward all calls |
|
|
1253
|
+
| `selective` | `ForwardingSetting` | Forward based on rules |
|
|
1254
|
+
| `rules` | `list[ForwardingRule]` | Selective forwarding rules |
|
|
1255
|
+
| `operating_modes` | `ForwardOperatingModes` | Mode-based forwarding |
|
|
1256
|
+
|
|
1257
|
+
#### `ForwardingSetting`
|
|
1258
|
+
|
|
1259
|
+
| Field | Type | Notes |
|
|
1260
|
+
|-------|------|-------|
|
|
1261
|
+
| `enabled` | `bool` | |
|
|
1262
|
+
| `destination` | `str` | Forwarding destination number |
|
|
1263
|
+
| `ring_reminder_enabled` | `bool` | Brief tone on forwarded call |
|
|
1264
|
+
| `destination_voice_mail_enabled` | `bool` | Forward to destination's voicemail |
|
|
1265
|
+
| `send_to_voicemail_enabled` | `bool` | Send to voicemail |
|
|
1266
|
+
|
|
1267
|
+
#### `ForwardingRule`
|
|
1268
|
+
Summary of a selective forwarding rule (returned in the rules list).
|
|
1269
|
+
|
|
1270
|
+
| Field | Type |
|
|
1271
|
+
|-------|------|
|
|
1272
|
+
| `id` | `str` |
|
|
1273
|
+
| `name` | `str` |
|
|
1274
|
+
| `calls_from` | `str` |
|
|
1275
|
+
| `forward_to` | `str` |
|
|
1276
|
+
| `calls_to` | `str` |
|
|
1277
|
+
| `enabled` | `bool` |
|
|
1278
|
+
|
|
1279
|
+
#### `ForwardingRuleDetails`
|
|
1280
|
+
Full details of a selective forwarding rule.
|
|
1281
|
+
|
|
1282
|
+
| Field | Type | Notes |
|
|
1283
|
+
|-------|------|-------|
|
|
1284
|
+
| `name` | `str` | |
|
|
1285
|
+
| `id` | `str` | |
|
|
1286
|
+
| `enabled` | `bool` | |
|
|
1287
|
+
| `holiday_schedule` | `str` | Schedule name for when rule applies |
|
|
1288
|
+
| `business_schedule` | `str` | Schedule name for when rule applies |
|
|
1289
|
+
| `forward_to` | `ForwardTo` | |
|
|
1290
|
+
| `calls_to` | `ForwardCallsTo` | List of numbers/extensions |
|
|
1291
|
+
| `calls_from` | `CallsFrom` | |
|
|
1292
|
+
|
|
1293
|
+
#### `ForwardTo`
|
|
1294
|
+
|
|
1295
|
+
| Field | Type | Default |
|
|
1296
|
+
|-------|------|---------|
|
|
1297
|
+
| `selection` | `ForwardToSelection` | `FORWARD_TO_DEFAULT_NUMBER` |
|
|
1298
|
+
| `phone_number` | `str` | |
|
|
1299
|
+
|
|
1300
|
+
#### `ForwardToSelection` (Enum)
|
|
1301
|
+
|
|
1302
|
+
| Value | Meaning |
|
|
1303
|
+
|-------|---------|
|
|
1304
|
+
| `FORWARD_TO_DEFAULT_NUMBER` | Use default forwarding number |
|
|
1305
|
+
| `FORWARD_TO_SPECIFIED_NUMBER` | Use number in `phone_number` field |
|
|
1306
|
+
| `DO_NOT_FORWARD` | Do not forward |
|
|
1307
|
+
|
|
1308
|
+
#### `ForwardFromSelection` (Enum)
|
|
1309
|
+
|
|
1310
|
+
| Value | Meaning |
|
|
1311
|
+
|-------|---------|
|
|
1312
|
+
| `ANY` | Match any caller |
|
|
1313
|
+
| `CUSTOM` | Match specific callers only |
|
|
1314
|
+
|
|
1315
|
+
#### `CallsFrom`
|
|
1316
|
+
|
|
1317
|
+
| Field | Type | Default |
|
|
1318
|
+
|-------|------|---------|
|
|
1319
|
+
| `selection` | `ForwardFromSelection` | `ANY` |
|
|
1320
|
+
| `custom_numbers` | `CustomNumbers` | |
|
|
1321
|
+
|
|
1322
|
+
#### `CustomNumbers`
|
|
1323
|
+
|
|
1324
|
+
| Field | Type | Default |
|
|
1325
|
+
|-------|------|---------|
|
|
1326
|
+
| `private_number_enabled` | `bool` | `False` |
|
|
1327
|
+
| `unavailable_number_enabled` | `bool` | `False` |
|
|
1328
|
+
| `numbers` | `list[str]` | |
|
|
1329
|
+
|
|
1330
|
+
#### `ForwardOperatingModes`
|
|
1331
|
+
|
|
1332
|
+
| Field | Type | Notes |
|
|
1333
|
+
|-------|------|-------|
|
|
1334
|
+
| `enabled` | `bool` | Operating modes enabled |
|
|
1335
|
+
| `current_operating_mode_id` | `str` | Currently active mode |
|
|
1336
|
+
| `exception_type` | `ExceptionType` | |
|
|
1337
|
+
| `modes` | `list[ModeForward]` | Configured modes |
|
|
1338
|
+
|
|
1339
|
+
#### `ModeForward`
|
|
1340
|
+
|
|
1341
|
+
| Field | Type |
|
|
1342
|
+
|-------|------|
|
|
1343
|
+
| `normal_operation_enabled` | `bool` |
|
|
1344
|
+
| `id` | `str` |
|
|
1345
|
+
| `name` | `str` |
|
|
1346
|
+
| `type` | `OperatingModeSchedule` |
|
|
1347
|
+
| `level` | `ScheduleLevel` |
|
|
1348
|
+
| `forward_to` | `ModeForwardTo` |
|
|
1349
|
+
|
|
1350
|
+
#### `ModeForwardTo`
|
|
1351
|
+
|
|
1352
|
+
| Field | Type | Notes |
|
|
1353
|
+
|-------|------|-------|
|
|
1354
|
+
| `selection` | `ForwardToSelection` | |
|
|
1355
|
+
| `destination` | `str` | Required when selection is `FORWARD_TO_SPECIFIED_NUMBER` |
|
|
1356
|
+
| `destination_voicemail_enabled` | `bool` | |
|
|
1357
|
+
| `default_destination` | `str` | Operating mode's own destination |
|
|
1358
|
+
| `default_destination_voicemail_enabled` | `bool` | |
|
|
1359
|
+
| `default_forward_to_selection` | `ModeDefaultForwardToSelection` | |
|
|
1360
|
+
|
|
1361
|
+
### 8.3 API Methods
|
|
1362
|
+
|
|
1363
|
+
```python
|
|
1364
|
+
class ForwardingApi:
|
|
1365
|
+
|
|
1366
|
+
def __init__(self, session: RestSession, feature_selector: FeatureSelector)
|
|
1367
|
+
|
|
1368
|
+
# --- Get/Update forwarding settings ---
|
|
1369
|
+
def settings(self, location_id: str, feature_id: str, org_id: str = None) -> CallForwarding
|
|
1370
|
+
def update(self, location_id: str, feature_id: str,
|
|
1371
|
+
forwarding: CallForwarding, org_id: str = None)
|
|
1372
|
+
|
|
1373
|
+
# --- Selective forwarding rules ---
|
|
1374
|
+
def create_call_forwarding_rule(self, location_id: str, feature_id: str,
|
|
1375
|
+
forwarding_rule: ForwardingRuleDetails,
|
|
1376
|
+
org_id: str = None) -> str # returns rule ID
|
|
1377
|
+
|
|
1378
|
+
def call_forwarding_rule(self, location_id: str, feature_id: str,
|
|
1379
|
+
rule_id: str, org_id: str = None) -> ForwardingRuleDetails
|
|
1380
|
+
|
|
1381
|
+
def update_call_forwarding_rule(self, location_id: str, feature_id: str,
|
|
1382
|
+
rule_id: str, forwarding_rule: ForwardingRuleDetails,
|
|
1383
|
+
org_id: str = None) -> str # returns new rule ID
|
|
1384
|
+
|
|
1385
|
+
def delete_call_forwarding_rule(self, location_id: str, feature_id: str,
|
|
1386
|
+
rule_id: str, org_id: str = None)
|
|
1387
|
+
|
|
1388
|
+
# --- Operating mode switch ---
|
|
1389
|
+
def switch_mode_for_call_forwarding(self, location_id: str, feature_id: str,
|
|
1390
|
+
org_id: str = None)
|
|
1391
|
+
```
|
|
1392
|
+
|
|
1393
|
+
### 8.4 CLI Examples
|
|
1394
|
+
|
|
1395
|
+
Forwarding commands are accessed through the feature-specific command groups (`auto-attendant`, `call-queue`, `hunt-group`), not a standalone forwarding group. The commands follow the same pattern across all three features:
|
|
1396
|
+
|
|
1397
|
+
```bash
|
|
1398
|
+
# --- Call Queue forwarding ---
|
|
1399
|
+
|
|
1400
|
+
# Get call forwarding settings for a call queue
|
|
1401
|
+
wxcli call-queue show-call-forwarding <location_id> <queue_id>
|
|
1402
|
+
|
|
1403
|
+
# Update call forwarding settings (use --json-body for complex forwarding rules)
|
|
1404
|
+
wxcli call-queue update-call-forwarding <location_id> <queue_id> --json-body '{
|
|
1405
|
+
"callForwarding": {
|
|
1406
|
+
"always": {"enabled": true, "destination": "+14155551234"}
|
|
1407
|
+
}
|
|
1408
|
+
}'
|
|
1409
|
+
|
|
1410
|
+
# Create a selective call forwarding rule
|
|
1411
|
+
wxcli call-queue create-selective-rules <location_id> <queue_id> \
|
|
1412
|
+
--name "After Hours Forward" --enabled \
|
|
1413
|
+
--business-schedule "After Hours Schedule"
|
|
1414
|
+
|
|
1415
|
+
# Get a selective call forwarding rule
|
|
1416
|
+
wxcli call-queue show-selective-rules <location_id> <queue_id> <rule_id>
|
|
1417
|
+
|
|
1418
|
+
# Delete a selective call forwarding rule
|
|
1419
|
+
wxcli call-queue delete-selective-rules <location_id> <queue_id> <rule_id>
|
|
1420
|
+
|
|
1421
|
+
# Get available phone numbers for call forwarding
|
|
1422
|
+
wxcli call-queue list-available-numbers-call-forwarding <location_id> <queue_id>
|
|
1423
|
+
|
|
1424
|
+
# Switch operating mode back to normal operations
|
|
1425
|
+
wxcli call-queue switch-mode-for <location_id> <queue_id>
|
|
1426
|
+
|
|
1427
|
+
# --- Auto Attendant forwarding (same pattern) ---
|
|
1428
|
+
wxcli auto-attendant show-call-forwarding <location_id> <aa_id>
|
|
1429
|
+
wxcli auto-attendant create-selective-rules <location_id> <aa_id> --name "Holiday Forward"
|
|
1430
|
+
wxcli auto-attendant switch-mode-for <location_id> <aa_id>
|
|
1431
|
+
|
|
1432
|
+
# --- Hunt Group forwarding (same pattern) ---
|
|
1433
|
+
wxcli hunt-group show-call-forwarding <location_id> <hg_id>
|
|
1434
|
+
wxcli hunt-group create-selective-rules <location_id> <hg_id> --name "Overflow Forward"
|
|
1435
|
+
wxcli hunt-group switch-mode-for <location_id> <hg_id>
|
|
1436
|
+
```
|
|
1437
|
+
|
|
1438
|
+
### 8.5 Key Behaviors
|
|
1439
|
+
|
|
1440
|
+
- **Rule ID changes on rename**: The Call Forwarding Rule ID will change when the rule name is modified via `update_call_forwarding_rule()`. The new ID is returned.
|
|
1441
|
+
- **NANP number normalization**: The SDK automatically handles +1 prefix transformations. Numbers returned from the platform without a `+` prefix get `+1-` prepended. When serializing for API calls, `+1-` is stripped back off. Non-NANP numbers (those starting with `+`) are left as-is.
|
|
1442
|
+
- **`switch_mode_for_call_forwarding()`** switches the feature's current operating mode back to normal operations.
|
|
1443
|
+
- The `update()` method serializes with `exclude_unset=True`, so only fields you explicitly set are sent to the API. It also strips read-only fields (`calls_from`, `forward_to`, `calls_to`, `name`) from rule summaries in the rules list.
|
|
1444
|
+
- **`CallForwarding.default()`** provides a safe starting point: always-forward disabled, selective disabled, empty rules list.
|
|
1445
|
+
- Three forwarding modes are available simultaneously: always forward, selective rules, and operating mode-based. The API returns all three as part of the `CallForwarding` object.
|
|
1446
|
+
|
|
1447
|
+
---
|
|
1448
|
+
|
|
1449
|
+
## Cross-Reference: Scope Summary
|
|
1450
|
+
|
|
1451
|
+
| API | Read Scope | Write Scope |
|
|
1452
|
+
|-----|-----------|-------------|
|
|
1453
|
+
| Call Recording | `spark-admin:telephony_config_read` | `spark-admin:telephony_config_write` |
|
|
1454
|
+
| Caller Reputation | `spark-admin:telephony_config_read` | `spark-admin:telephony_config_write` |
|
|
1455
|
+
| Conference Controls | `spark:calls_read` | `spark:calls_write` |
|
|
1456
|
+
| Supervisors | `spark-admin:telephony_config_read` | `spark-admin:telephony_config_write` |
|
|
1457
|
+
| Guest Calling | `spark-admin:telephony_config_read` | `spark-admin:telephony_config_write` |
|
|
1458
|
+
| Operating Modes | `spark-admin:telephony_config_read` | `spark-admin:telephony_config_write` |
|
|
1459
|
+
| Hot Desking Voice Portal | `spark-admin:telephony_config_read` | `spark-admin:telephony_config_write` |
|
|
1460
|
+
| Forwarding | `spark-admin:telephony_config_read` | `spark-admin:telephony_config_write` |
|
|
1461
|
+
|
|
1462
|
+
Note that Conference Controls uses **user-level** scopes (`spark:calls_*`), not admin scopes, because it is a runtime call-control API.
|
|
1463
|
+
|
|
1464
|
+
---
|
|
1465
|
+
|
|
1466
|
+
## Gotchas (Cross-Cutting)
|
|
1467
|
+
|
|
1468
|
+
- **Conference Controls require user-level OAuth.** Unlike all other APIs in this doc, Conference Controls uses `spark:calls_read` / `spark:calls_write` scopes (not admin scopes). Admin or service-app tokens will fail. This matches the `call-controls` known issue documented in CLAUDE.md.
|
|
1469
|
+
- **Caller Reputation uses `organizationId`, not `orgId`.** Most telephony APIs use `orgId` as the query parameter, but the caller reputation endpoints use `organizationId`. The wxcli maps this as `--organization-id`.
|
|
1470
|
+
- **Call Recording vendor changes are async.** `set_org_vendor()` and `set_location_vendor()` may return a job ID (HTTP 200) instead of completing immediately (HTTP 204). Always check job status via `wxcli call-recording show-call-recording <job_id>` after vendor changes.
|
|
1471
|
+
- **Operating mode type and level are immutable after creation.** You cannot change `type` (SAME_HOURS_DAILY, DIFFERENT_HOURS_DAILY, HOLIDAY) or `level` (ORGANIZATION, LOCATION) after creating an operating mode. Delete and recreate if you need to change these.
|
|
1472
|
+
- **Forwarding rule IDs change on rename.** When you rename a selective forwarding rule via `update_call_forwarding_rule()`, the rule ID changes. The new ID is returned from the update call. Store it if you need to reference the rule again.
|
|
1473
|
+
- **Score thresholds are strings.** The caller reputation `callBlockScoreThreshold` and `callAllowScoreThreshold` fields are string-typed, not integers. Pass them as quoted values in both CLI and raw HTTP.
|
|
1474
|
+
- **`delete_bulk` supervisors has a nuke option.** Setting `delete_all: true` on `delete_bulk()` ignores the provided ID list and removes ALL supervisors in the org. Double-check before using.
|
|
1475
|
+
- **Hot desking has two levels.** The location setting enables the feature globally for the location; the user-level setting controls whether a specific user can act as a hot desking guest. Both must be enabled for a user to hot-desk at that location.
|
|
1476
|
+
- **TimePeriod AXL field constraints.** The `monthOfYear` field uses 3-letter abbreviations only (`Dec`, `Jan`, `Feb`, etc., not full names like `December`). The `startTime`/`endTime` fields only accept on-the-hour values per the `TypeTimeOfDay` enum — values like `23:59` or `17:30` are rejected. For date-specific (holiday) time periods, use `monthOfYear` + `dayOfMonth` with valid time range (e.g., `08:00`–`17:00`).
|
|
1477
|
+
|
|
1478
|
+
---
|
|
1479
|
+
|
|
1480
|
+
## See Also
|
|
1481
|
+
|
|
1482
|
+
- **[Person Call Settings — Media](person-call-settings-media.md)** — Per-user call recording settings (record mode, notifications, access permissions) that work within the vendor/compliance framework configured here
|