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,1320 @@
|
|
|
1
|
+
# Call Features: Auto Attendants, Call Queues, and Hunt Groups
|
|
2
|
+
|
|
3
|
+
Reference for Webex Calling's three major call-routing features. Sourced from the `wxc_sdk` Python SDK.
|
|
4
|
+
|
|
5
|
+
## Sources
|
|
6
|
+
|
|
7
|
+
- wxc_sdk v1.30.0
|
|
8
|
+
- OpenAPI spec: specs/webex-cloud-calling.json
|
|
9
|
+
- developer.webex.com Call Features APIs
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Table of Contents
|
|
14
|
+
|
|
15
|
+
1. [Auto Attendants](#1-auto-attendants)
|
|
16
|
+
2. [Call Queues](#2-call-queues)
|
|
17
|
+
3. [Hunt Groups](#3-hunt-groups)
|
|
18
|
+
4. [Shared Forwarding API](#4-shared-forwarding-api)
|
|
19
|
+
5. [Common Data Models (HG/CQ Base)](#5-common-data-models-hgcq-base)
|
|
20
|
+
6. [Required Scopes](#6-required-scopes)
|
|
21
|
+
7. [Dependencies](#7-dependencies)
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## 1. Auto Attendants
|
|
26
|
+
|
|
27
|
+
### Overview
|
|
28
|
+
|
|
29
|
+
Auto attendants play customized prompts and provide callers with menu options for routing their calls. They support separate menus for business hours and after hours, each configurable with key-press actions (transfer, dial-by-name, extension dialing, repeat menu, exit, etc.).
|
|
30
|
+
|
|
31
|
+
Use an auto attendant when you need an IVR-style front door: "Press 1 for Sales, 2 for Support..."
|
|
32
|
+
|
|
33
|
+
**SDK access path:** `api.telephony.auto_attendant`
|
|
34
|
+
|
|
35
|
+
### API Operations
|
|
36
|
+
|
|
37
|
+
| Operation | Method | Signature |
|
|
38
|
+
|-----------|--------|-----------|
|
|
39
|
+
| **List** | `list()` | `list(org_id=None, location_id=None, name=None, phone_number=None, **params) -> Generator[AutoAttendant]` |
|
|
40
|
+
| **Get by name** | `by_name()` | `by_name(name, location_id=None, org_id=None) -> Optional[AutoAttendant]` |
|
|
41
|
+
| **Get details** | `details()` | `details(location_id, auto_attendant_id, org_id=None) -> AutoAttendant` |
|
|
42
|
+
| **Create** | `create()` | `create(location_id, settings: AutoAttendant, org_id=None) -> str` (returns new ID) |
|
|
43
|
+
| **Update** | `update()` | `update(location_id, auto_attendant_id, settings: AutoAttendant, org_id=None) -> None` |
|
|
44
|
+
| **Delete** | `delete_auto_attendant()` | `delete_auto_attendant(location_id, auto_attendant_id, org_id=None) -> None` |
|
|
45
|
+
|
|
46
|
+
### Key Data Models
|
|
47
|
+
|
|
48
|
+
#### `AutoAttendant`
|
|
49
|
+
|
|
50
|
+
| Field | Type | Required for Create | Notes |
|
|
51
|
+
|-------|------|:-------------------:|-------|
|
|
52
|
+
| `name` | `str` | Yes | Unique name |
|
|
53
|
+
| `phone_number` | `str` | One of phone_number/extension | |
|
|
54
|
+
| `extension` | `str` | One of phone_number/extension | |
|
|
55
|
+
| `business_schedule` | `str` | Yes | Name of business hours schedule |
|
|
56
|
+
| `holiday_schedule` | `str` | No | Name of holiday schedule |
|
|
57
|
+
| `business_hours_menu` | `AutoAttendantMenu` | Yes | Defaults to single key: 0 -> EXIT |
|
|
58
|
+
| `after_hours_menu` | `AutoAttendantMenu` | Yes | Defaults to single key: 0 -> EXIT |
|
|
59
|
+
| `extension_dialing` | `Dialing` | No | `ENTERPRISE` or `GROUP` (default: ENTERPRISE) |
|
|
60
|
+
| `name_dialing` | `Dialing` | No | `ENTERPRISE` or `GROUP` (default: ENTERPRISE) |
|
|
61
|
+
| `language_code` | `str` | No | |
|
|
62
|
+
| `time_zone` | `str` | No | |
|
|
63
|
+
| `alternate_numbers` | `list[AlternateNumber]` | No | Only in details(), up to 10 |
|
|
64
|
+
| `first_name` / `last_name` | `str` | No | **Deprecated** -- use `direct_line_caller_id_name` and `dial_by_name` instead |
|
|
65
|
+
| `direct_line_caller_id_name` | `DirectLineCallerIdName` | No | Not supported in FedRAMP. See [authentication.md → FedRAMP](authentication.md#webex-for-government-fedramp) for all FedRAMP restrictions. |
|
|
66
|
+
| `dial_by_name` | `str` | No | Not supported in FedRAMP. See [authentication.md → FedRAMP](authentication.md#webex-for-government-fedramp) for all FedRAMP restrictions. |
|
|
67
|
+
|
|
68
|
+
**Convenience constructor:**
|
|
69
|
+
```python
|
|
70
|
+
AutoAttendant.create(name="Main Menu",
|
|
71
|
+
business_schedule="Business Hours",
|
|
72
|
+
extension="1000")
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
#### `AutoAttendantMenu`
|
|
76
|
+
|
|
77
|
+
| Field | Type | Notes |
|
|
78
|
+
|-------|------|-------|
|
|
79
|
+
| `greeting` | `Greeting` | `DEFAULT` or `CUSTOM` |
|
|
80
|
+
| `extension_enabled` | `bool` | Allow extension dialing from this menu |
|
|
81
|
+
| `audio_announcement_file` | `AnnAudioFile` | Required when greeting is CUSTOM |
|
|
82
|
+
| `key_configurations` | `list[AutoAttendantKeyConfiguration]` | Key-to-action mappings |
|
|
83
|
+
| `call_treatment` | `CallTreatment` | What to do when caller gives no input |
|
|
84
|
+
|
|
85
|
+
#### `AutoAttendantKeyConfiguration`
|
|
86
|
+
|
|
87
|
+
| Field | Type | Notes |
|
|
88
|
+
|-------|------|-------|
|
|
89
|
+
| `key` | `MenuKey` | `0`-`9`, `*`, `#` |
|
|
90
|
+
| `action` | `AutoAttendantAction` | See enum below |
|
|
91
|
+
| `description` | `str` | Optional |
|
|
92
|
+
| `value` | `str` | Destination number/extension for transfer actions |
|
|
93
|
+
|
|
94
|
+
#### Enum: `AutoAttendantAction`
|
|
95
|
+
|
|
96
|
+
| Value | Description |
|
|
97
|
+
|-------|-------------|
|
|
98
|
+
| `TRANSFER_WITHOUT_PROMPT` | Transfer immediately |
|
|
99
|
+
| `TRANSFER_WITH_PROMPT` | Play prompt then transfer |
|
|
100
|
+
| `TRANSFER_TO_OPERATOR` | Transfer to operator |
|
|
101
|
+
| `NAME_DIALING` | Dial by name directory |
|
|
102
|
+
| `EXTENSION_DIALING` | Dial by extension |
|
|
103
|
+
| `REPEAT_MENU` | Replay the menu |
|
|
104
|
+
| `EXIT` | Disconnect |
|
|
105
|
+
| `TRANSFER_TO_MAILBOX` | Transfer to voicemail |
|
|
106
|
+
| `RETURN_TO_PREVIOUS_MENU` | Go back one menu level |
|
|
107
|
+
| `PLAY_ANNOUNCEMENT` | Play an announcement |
|
|
108
|
+
|
|
109
|
+
#### `CallTreatment` (no-input handling)
|
|
110
|
+
|
|
111
|
+
| Field | Type | Notes |
|
|
112
|
+
|-------|------|-------|
|
|
113
|
+
| `retry_attempt_for_no_input` | `CallTreatmentRetry` | `NO_REPEAT`, `ONE_TIME`, `TWO_TIMES`, `THREE_TIMES` |
|
|
114
|
+
| `no_input_timer` | `int` | Seconds to wait (1-60, default 10) |
|
|
115
|
+
| `action_to_be_performed` | `ActionToBePerformed` | What to do after retries exhausted |
|
|
116
|
+
|
|
117
|
+
#### `ActionToBePerformedAction` (post-retry actions)
|
|
118
|
+
|
|
119
|
+
`PLAY_MESSAGE_AND_DISCONNECT`, `TRANSFER_WITHOUT_PROMPT`, `TRANSFER_WITH_PROMPT`, `TRANSFER_TO_OPERATOR`, `TRANSFER_TO_MAILBOX`, `DISCONNECT`
|
|
120
|
+
|
|
121
|
+
### Phone Number/Extension Assignment
|
|
122
|
+
|
|
123
|
+
- Must provide at least one of `phone_number` or `extension` at creation.
|
|
124
|
+
- Available numbers for assignment:
|
|
125
|
+
- `primary_available_phone_numbers(location_id, ...)` -- unassigned numbers at the location
|
|
126
|
+
- `alternate_available_phone_numbers(location_id, ...)` -- numbers for alternate number assignment
|
|
127
|
+
- `call_forward_available_phone_numbers(location_id, ...)` -- assigned numbers available for forwarding
|
|
128
|
+
|
|
129
|
+
### Announcements
|
|
130
|
+
|
|
131
|
+
- `list_announcement_files(location_id, auto_attendant_id, org_id=None) -> list[AnnAudioFile]`
|
|
132
|
+
- `delete_announcement_file(location_id, auto_attendant_id, file_name, org_id=None)`
|
|
133
|
+
- **Upload is supported via the Announcement Repository API** (`POST /telephony/config/announcements` or `POST /telephony/config/locations/{locationId}/announcements` with multipart/form-data). See [location-calling-media.md](location-calling-media.md) section 1.
|
|
134
|
+
|
|
135
|
+
### Forwarding
|
|
136
|
+
|
|
137
|
+
Auto attendants have a `forwarding` sub-API (instance of `ForwardingApi` with `FeatureSelector.auto_attendants`). See [Shared Forwarding API](#4-shared-forwarding-api).
|
|
138
|
+
|
|
139
|
+
### Raw HTTP
|
|
140
|
+
<!-- Updated by playbook session 2026-03-18 -->
|
|
141
|
+
|
|
142
|
+
```python
|
|
143
|
+
from wxc_sdk import WebexSimpleApi
|
|
144
|
+
api = WebexSimpleApi() # auth via WEBEX_ACCESS_TOKEN env var
|
|
145
|
+
BASE = "https://webexapis.com/v1"
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
**List auto attendants:**
|
|
149
|
+
```python
|
|
150
|
+
params = {"locationId": loc_id, "max": 1000}
|
|
151
|
+
result = api.session.rest_get(f"{BASE}/telephony/config/autoAttendants", params=params)
|
|
152
|
+
aas = result.get("autoAttendants", [])
|
|
153
|
+
# Each item: {"id", "name", "locationId", "locationName", "phoneNumber", "extension", "enabled", ...}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
**Get details:**
|
|
157
|
+
```python
|
|
158
|
+
aa = api.session.rest_get(f"{BASE}/telephony/config/locations/{loc_id}/autoAttendants/{aa_id}")
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
**Create auto attendant:**
|
|
162
|
+
```python
|
|
163
|
+
body = {
|
|
164
|
+
"name": "Main Menu",
|
|
165
|
+
"extension": "1000",
|
|
166
|
+
"businessSchedule": "Business Hours", # must reference existing schedule
|
|
167
|
+
"businessHoursMenu": {
|
|
168
|
+
"greeting": "DEFAULT",
|
|
169
|
+
"extensionEnabled": True,
|
|
170
|
+
"keyConfigurations": [{"key": "0", "action": "EXIT"}]
|
|
171
|
+
},
|
|
172
|
+
"afterHoursMenu": {
|
|
173
|
+
"greeting": "DEFAULT",
|
|
174
|
+
"extensionEnabled": True,
|
|
175
|
+
"keyConfigurations": [{"key": "0", "action": "EXIT"}]
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
result = api.session.rest_post(f"{BASE}/telephony/config/locations/{loc_id}/autoAttendants", json=body)
|
|
179
|
+
new_id = result.get("id")
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Required fields: `name`, `extension` (or `phoneNumber`), `businessSchedule`, `businessHoursMenu`, `afterHoursMenu`. Both menus need `greeting`, `extensionEnabled`, and at least one `keyConfigurations` entry.
|
|
183
|
+
|
|
184
|
+
**Update auto attendant:**
|
|
185
|
+
```python
|
|
186
|
+
body = {"name": "Updated Menu Name"} # partial update — only changed fields
|
|
187
|
+
api.session.rest_put(f"{BASE}/telephony/config/locations/{loc_id}/autoAttendants/{aa_id}", json=body)
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
**Delete auto attendant:**
|
|
191
|
+
```python
|
|
192
|
+
api.session.rest_delete(f"{BASE}/telephony/config/locations/{loc_id}/autoAttendants/{aa_id}")
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
**Get call forwarding settings:**
|
|
196
|
+
```python
|
|
197
|
+
fwd = api.session.rest_get(
|
|
198
|
+
f"{BASE}/telephony/config/locations/{loc_id}/autoAttendants/{aa_id}/callForwarding"
|
|
199
|
+
)
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### CLI Examples
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
# List all auto attendants (org-wide)
|
|
206
|
+
wxcli auto-attendant list
|
|
207
|
+
|
|
208
|
+
# List auto attendants at a specific location
|
|
209
|
+
wxcli auto-attendant list --location-id Y2lzY29zcGFyazovL...
|
|
210
|
+
|
|
211
|
+
# Filter by name
|
|
212
|
+
wxcli auto-attendant list --name "Main Menu"
|
|
213
|
+
|
|
214
|
+
# Get details for a specific auto attendant (JSON output)
|
|
215
|
+
wxcli auto-attendant show Y2lzY29zcGFyazovL_LOC_ID Y2lzY29zcGFyazovL_AA_ID
|
|
216
|
+
|
|
217
|
+
# Create a minimal auto attendant (basic fields only)
|
|
218
|
+
wxcli auto-attendant create Y2lzY29zcGFyazovL_LOC_ID \
|
|
219
|
+
--name "Main Menu" \
|
|
220
|
+
--extension "1000" \
|
|
221
|
+
--business-schedule "Business Hours"
|
|
222
|
+
|
|
223
|
+
# Create with full menu configuration via --json-body
|
|
224
|
+
wxcli auto-attendant create Y2lzY29zcGFyazovL_LOC_ID --json-body '{
|
|
225
|
+
"name": "Main Menu",
|
|
226
|
+
"extension": "1000",
|
|
227
|
+
"businessSchedule": "Business Hours",
|
|
228
|
+
"businessHoursMenu": {
|
|
229
|
+
"greeting": "DEFAULT",
|
|
230
|
+
"extensionEnabled": true,
|
|
231
|
+
"keyConfigurations": [
|
|
232
|
+
{"key": "1", "action": "TRANSFER_WITHOUT_PROMPT", "value": "2000"},
|
|
233
|
+
{"key": "2", "action": "TRANSFER_WITHOUT_PROMPT", "value": "3000"},
|
|
234
|
+
{"key": "0", "action": "TRANSFER_TO_OPERATOR", "value": ""}
|
|
235
|
+
]
|
|
236
|
+
},
|
|
237
|
+
"afterHoursMenu": {
|
|
238
|
+
"greeting": "DEFAULT",
|
|
239
|
+
"extensionEnabled": true,
|
|
240
|
+
"keyConfigurations": [{"key": "0", "action": "EXIT", "value": ""}]
|
|
241
|
+
}
|
|
242
|
+
}'
|
|
243
|
+
|
|
244
|
+
# Update basic fields (name, extension)
|
|
245
|
+
wxcli auto-attendant update Y2lzY29zcGFyazovL_LOC_ID Y2lzY29zcGFyazovL_AA_ID \
|
|
246
|
+
--name "Updated Main Menu"
|
|
247
|
+
|
|
248
|
+
# Update menu configuration via --json-body (required for menu changes)
|
|
249
|
+
wxcli auto-attendant update Y2lzY29zcGFyazovL_LOC_ID Y2lzY29zcGFyazovL_AA_ID --json-body '{
|
|
250
|
+
"businessHoursMenu": {
|
|
251
|
+
"greeting": "DEFAULT",
|
|
252
|
+
"extensionEnabled": true,
|
|
253
|
+
"keyConfigurations": [
|
|
254
|
+
{"key": "1", "action": "TRANSFER_WITHOUT_PROMPT", "value": "2000"},
|
|
255
|
+
{"key": "0", "action": "EXIT", "value": ""}
|
|
256
|
+
]
|
|
257
|
+
}
|
|
258
|
+
}'
|
|
259
|
+
|
|
260
|
+
# Delete an auto attendant
|
|
261
|
+
wxcli auto-attendant delete Y2lzY29zcGFyazovL_LOC_ID Y2lzY29zcGFyazovL_AA_ID --force
|
|
262
|
+
|
|
263
|
+
# Get call forwarding settings
|
|
264
|
+
wxcli auto-attendant show-call-forwarding Y2lzY29zcGFyazovL_LOC_ID Y2lzY29zcGFyazovL_AA_ID
|
|
265
|
+
|
|
266
|
+
# List announcement files
|
|
267
|
+
wxcli auto-attendant list-announcements Y2lzY29zcGFyazovL_LOC_ID Y2lzY29zcGFyazovL_AA_ID
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
---
|
|
271
|
+
|
|
272
|
+
## 2. Call Queues
|
|
273
|
+
|
|
274
|
+
### Overview
|
|
275
|
+
|
|
276
|
+
Call queues temporarily hold calls in the cloud when all assigned agents are unavailable. Queued calls route to agents when they become available. Each queue has a lead number (external phone number) and an internal extension.
|
|
277
|
+
|
|
278
|
+
Use a call queue when callers should wait on hold until an agent is free (support lines, order lines, etc.).
|
|
279
|
+
|
|
280
|
+
**SDK access path:** `api.telephony.callqueue`
|
|
281
|
+
|
|
282
|
+
### API Operations
|
|
283
|
+
|
|
284
|
+
| Operation | Method | Signature |
|
|
285
|
+
|-----------|--------|-----------|
|
|
286
|
+
| **List** | `list()` | `list(location_id=None, name=None, phone_number=None, department_id=None, department_name=None, has_cx_essentials=None, org_id=None, **params) -> Generator[CallQueue]` |
|
|
287
|
+
| **Get by name** | `by_name()` | `by_name(name, location_id=None, has_cx_essentials=None, org_id=None) -> Optional[CallQueue]` |
|
|
288
|
+
| **Get details** | `details()` | `details(location_id, queue_id, has_cx_essentials=None, org_id=None) -> CallQueue` |
|
|
289
|
+
| **Create** | `create()` | `create(location_id, settings: CallQueue, has_cx_essentials=None, org_id=None) -> str` |
|
|
290
|
+
| **Update** | `update()` | `update(location_id, queue_id, update: CallQueue, org_id=None) -> None` |
|
|
291
|
+
| **Delete** | `delete_queue()` | `delete_queue(location_id, queue_id, org_id=None) -> None` |
|
|
292
|
+
| **Org-level settings** | `get_call_queue_settings()` | `get_call_queue_settings(org_id=None) -> CallQueueSettings` |
|
|
293
|
+
| **Update org settings** | `update_call_queue_settings()` | `update_call_queue_settings(settings: CallQueueSettings, org_id=None) -> None` |
|
|
294
|
+
| **Available agents** | `available_agents()` | `available_agents(location_id, name=None, phone_number=None, order=None, org_id=None) -> Generator[AvailableAgent]` |
|
|
295
|
+
|
|
296
|
+
### Key Data Models
|
|
297
|
+
|
|
298
|
+
#### `CallQueue` (extends `HGandCQ`)
|
|
299
|
+
|
|
300
|
+
| Field | Type | Required for Create | Notes |
|
|
301
|
+
|-------|------|:-------------------:|-------|
|
|
302
|
+
| `name` | `str` | Yes | Unique name |
|
|
303
|
+
| `phone_number` | `str` | One of phone_number/extension | |
|
|
304
|
+
| `extension` | `str` | One of phone_number/extension | |
|
|
305
|
+
| `agents` | `list[Agent]` | Yes | People, workspaces, or virtual lines |
|
|
306
|
+
| `call_policies` | `CallQueueCallPolicies` | Yes | Routing type, policy, call bounce, distinctive ring |
|
|
307
|
+
| `queue_settings` | `QueueSettings` | Yes | Queue size, overflow, announcements |
|
|
308
|
+
| `enabled` | `bool` | No | |
|
|
309
|
+
| `language_code` | `str` | No | |
|
|
310
|
+
| `time_zone` | `str` | No | |
|
|
311
|
+
| `allow_call_waiting_for_agents_enabled` | `bool` | No | |
|
|
312
|
+
| `allow_agent_join_enabled` | `bool` | No | Let agents join/unjoin |
|
|
313
|
+
| `phone_number_for_outgoing_calls_enabled` | `bool` | No | Allow queue number for outbound caller ID |
|
|
314
|
+
| `department` | `IdAndName` | No | |
|
|
315
|
+
| `has_cx_essentials` | `bool` | No | Customer Assist (formerly CX Essentials) license flag |
|
|
316
|
+
|
|
317
|
+
**Convenience constructor:**
|
|
318
|
+
```python
|
|
319
|
+
CallQueue.create(name="Support Queue",
|
|
320
|
+
agents=[Agent(agent_id=user.person_id) for user in members],
|
|
321
|
+
queue_size=10,
|
|
322
|
+
extension="2000")
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
#### `CallQueueCallPolicies`
|
|
326
|
+
|
|
327
|
+
| Field | Type | Notes |
|
|
328
|
+
|-------|------|-------|
|
|
329
|
+
| `routing_type` | `CQRoutingType` | `PRIORITY_BASED` or `SKILL_BASED` |
|
|
330
|
+
| `policy` | `Policy` | See Policy enum below |
|
|
331
|
+
| `call_bounce` | `CallBounce` | No-answer behavior |
|
|
332
|
+
| `distinctive_ring` | `DistinctiveRing` | Optional ring pattern |
|
|
333
|
+
|
|
334
|
+
#### Enum: `Policy` (shared with Hunt Groups)
|
|
335
|
+
|
|
336
|
+
| Value | Max Agents | Description |
|
|
337
|
+
|-------|:----------:|-------------|
|
|
338
|
+
| `CIRCULAR` | 1,000 | Round-robin after last agent that took a call |
|
|
339
|
+
| `REGULAR` | 1,000 | Top-down, restart from top each time |
|
|
340
|
+
| `SIMULTANEOUS` | 50 | Ring all agents at once |
|
|
341
|
+
| `UNIFORM` | 1,000 | Longest-idle agent first |
|
|
342
|
+
| `WEIGHTED` | 100 | Percentage-based distribution (up to 100%) |
|
|
343
|
+
|
|
344
|
+
#### Enum: `CQRoutingType`
|
|
345
|
+
|
|
346
|
+
| Value | Description |
|
|
347
|
+
|-------|-------------|
|
|
348
|
+
| `PRIORITY_BASED` | Uses routing policy directly |
|
|
349
|
+
| `SKILL_BASED` | Routes by agent skill level; policy is tiebreaker when skill levels match |
|
|
350
|
+
|
|
351
|
+
#### `CallBounce`
|
|
352
|
+
|
|
353
|
+
| Field | Type | Default | Notes |
|
|
354
|
+
|-------|------|---------|-------|
|
|
355
|
+
| `enabled` (alias: `callBounceEnabled`) | `bool` | `True` | Bounce after max_rings |
|
|
356
|
+
| `max_rings` (alias: `callBounceMaxRings`) | `int` | `5` | |
|
|
357
|
+
| `agent_unavailable_enabled` | `bool` | `True` | Bounce if agent goes unavailable |
|
|
358
|
+
| `alert_agent_enabled` | `bool` | `True` | Alert agent for long-held calls |
|
|
359
|
+
| `alert_agent_max_seconds` | `int` | `30` | |
|
|
360
|
+
| `on_hold_enabled` | `bool` | `False` | Bounce calls on hold too long |
|
|
361
|
+
| `on_hold_max_seconds` | `int` | `60` | |
|
|
362
|
+
|
|
363
|
+
### Overflow Settings
|
|
364
|
+
|
|
365
|
+
#### `OverflowSetting` (inside `QueueSettings.overflow`)
|
|
366
|
+
|
|
367
|
+
| Field | Type | Notes |
|
|
368
|
+
|-------|------|-------|
|
|
369
|
+
| `action` | `OverflowAction` | What happens when queue is full |
|
|
370
|
+
| `send_to_voicemail` | `bool` | Forward to voicemail of internal number |
|
|
371
|
+
| `transfer_number` | `str` | Destination when action is TRANSFER_TO_PHONE_NUMBER |
|
|
372
|
+
| `overflow_after_wait_enabled` | `bool` | Trigger overflow after wait time |
|
|
373
|
+
| `overflow_after_wait_time` | `int` | Seconds before overflow triggers (no agent available) |
|
|
374
|
+
| `play_overflow_greeting_enabled` | `bool` | Play audio before overflow action |
|
|
375
|
+
| `greeting` | `Greeting` | `DEFAULT` or `CUSTOM` |
|
|
376
|
+
| `audio_announcement_files` | `list[AnnAudioFile]` | 1-4 files for CUSTOM greeting |
|
|
377
|
+
|
|
378
|
+
#### Enum: `OverflowAction`
|
|
379
|
+
|
|
380
|
+
| Value | Description |
|
|
381
|
+
|-------|-------------|
|
|
382
|
+
| `PERFORM_BUSY_TREATMENT` | Caller hears fast-busy tone |
|
|
383
|
+
| `TRANSFER_TO_PHONE_NUMBER` | Transfer to specified number |
|
|
384
|
+
| `PLAY_RINGING_UNTIL_CALLER_HANGS_UP` | Caller hears ringing until disconnect |
|
|
385
|
+
|
|
386
|
+
### Queue Settings and Announcements
|
|
387
|
+
|
|
388
|
+
`QueueSettings` contains the full queue behavior configuration:
|
|
389
|
+
|
|
390
|
+
| Field | Type | Notes |
|
|
391
|
+
|-------|------|-------|
|
|
392
|
+
| `queue_size` | `int` | Maximum calls in queue; overflow triggers when exceeded |
|
|
393
|
+
| `call_offer_tone_enabled` | `bool` | Play tone to callers when routed to agent |
|
|
394
|
+
| `reset_call_statistics_enabled` | `bool` | Reset stats on queue entry |
|
|
395
|
+
| `overflow` | `OverflowSetting` | See above |
|
|
396
|
+
| `welcome_message` | `WelcomeMessageSetting` | First message callers hear; can be mandatory |
|
|
397
|
+
| `wait_message` | `WaitMessageSetting` | Estimated wait time or position |
|
|
398
|
+
| `comfort_message` | `ComfortMessageSetting` | Periodic message (promotions, info) |
|
|
399
|
+
| `comfort_message_bypass` | `ComfortMessageBypass` | Short comfort for quickly-answered calls |
|
|
400
|
+
| `moh_message` | `MohMessageSetting` | Music on hold (normal + alternate source) |
|
|
401
|
+
| `whisper_message` | `AudioSource` | Plays to agent before connection (identifies queue) |
|
|
402
|
+
|
|
403
|
+
#### `WelcomeMessageSetting` (extends `AudioSource`)
|
|
404
|
+
|
|
405
|
+
- `enabled`, `greeting` (`DEFAULT`/`CUSTOM`), `audio_announcement_files`
|
|
406
|
+
- `always_enabled`: If true, message plays even when agent is immediately available.
|
|
407
|
+
|
|
408
|
+
#### `WaitMessageSetting`
|
|
409
|
+
|
|
410
|
+
| Field | Type | Notes |
|
|
411
|
+
|-------|------|-------|
|
|
412
|
+
| `enabled` | `bool` | |
|
|
413
|
+
| `wait_mode` | `WaitMode` | `TIME` or `POSITION` |
|
|
414
|
+
| `handling_time` | `int` | Minutes for estimated wait (10-100) |
|
|
415
|
+
| `default_handling_time` | `int` | Default handling minutes (1-100) |
|
|
416
|
+
| `queue_position` | `int` | Position threshold (10-100) |
|
|
417
|
+
| `high_volume_message_enabled` | `bool` | |
|
|
418
|
+
| `estimated_waiting_time` | `int` | Seconds (10-600) |
|
|
419
|
+
| `callback_option_enabled` | `bool` | Default: false |
|
|
420
|
+
| `minimum_estimated_callback_time` | `int` | Minutes; default: 30 |
|
|
421
|
+
| `international_callback_enabled` | `bool` | Default: false |
|
|
422
|
+
| `play_updated_estimated_wait_message` | `bool` | |
|
|
423
|
+
|
|
424
|
+
#### `ComfortMessageSetting`
|
|
425
|
+
|
|
426
|
+
- `enabled`, `greeting`, `audio_announcement_files`
|
|
427
|
+
- `time_between_messages`: Interval in seconds (10-600, default 10)
|
|
428
|
+
|
|
429
|
+
#### `ComfortMessageBypass`
|
|
430
|
+
|
|
431
|
+
- `enabled`, `greeting`, `audio_announcement_files`
|
|
432
|
+
- `call_waiting_age_threshold`: Seconds (default 30)
|
|
433
|
+
- `play_announcement_after_ringing`: bool
|
|
434
|
+
- `ring_time_before_playing_announcement`: Seconds (default 10)
|
|
435
|
+
|
|
436
|
+
#### `MohMessageSetting`
|
|
437
|
+
|
|
438
|
+
- `normal_source`: `AudioSource` -- primary music on hold
|
|
439
|
+
- `alternate_source`: `AudioSource` -- alternate music on hold
|
|
440
|
+
|
|
441
|
+
### Agent/Member Management
|
|
442
|
+
|
|
443
|
+
Agents can be people, workspaces, or virtual lines. The `Agent` model (from `hg_and_cq`):
|
|
444
|
+
|
|
445
|
+
| Field | Type | Notes |
|
|
446
|
+
|-------|------|-------|
|
|
447
|
+
| `agent_id` (alias: `id`) | `str` | Person/workspace/virtual line ID |
|
|
448
|
+
| `weight` | `str` | Only for WEIGHTED policy |
|
|
449
|
+
| `skill_level` | `int` | Only for SKILL_BASED routing |
|
|
450
|
+
| `join_enabled` | `bool` | Only for call queues -- agent's join status |
|
|
451
|
+
|
|
452
|
+
**Agents sub-API** (`api.telephony.callqueue.agents`):
|
|
453
|
+
|
|
454
|
+
| Method | Signature | Notes |
|
|
455
|
+
|--------|-----------|-------|
|
|
456
|
+
| `list()` | `list(location_id=None, queue_id=None, name=None, phone_number=None, join_enabled=None, has_cx_essentials=None, order=None, org_id=None) -> Generator[CallQueueAgent]` | List all agents across queues |
|
|
457
|
+
| `details()` | `details(id, has_cx_essentials=None, max_=50, start=0, org_id=None) -> CallQueueAgentDetail` | Get agent detail with their queue assignments |
|
|
458
|
+
| `update_call_queue_settings()` | `update_call_queue_settings(id, settings: list[AgentCallQueueSetting], has_cx_essentials=None, org_id=None)` | Update an agent's join status across multiple queues |
|
|
459
|
+
|
|
460
|
+
**Known SDK note:** The decoded value of the agent's `id` and the `type` returned are always `PEOPLE`, even for workspaces or virtual lines. This is a known platform issue that persists as of 2026-03-19. The OpenAPI spec defines `MemberType` as `["PEOPLE", "PLACE"]` and `GetPersonPlaceVirtualLineCallQueueObject.type` as `["PEOPLE", "PLACE", "VIRTUAL_LINE"]`, but the live API returns `"type": "PEOPLE"` for all agent types in queue detail responses. The `availableUsers` endpoint correctly returns `PLACE` and `VIRTUAL_LINE` types, but once assigned to a queue the type collapses to `PEOPLE`.
|
|
461
|
+
|
|
462
|
+
**Adding/removing agents from a queue** (from examples):
|
|
463
|
+
```python
|
|
464
|
+
# Add agents
|
|
465
|
+
details = api.telephony.callqueue.details(location_id=loc_id, queue_id=q_id)
|
|
466
|
+
details.agents.append(Agent(agent_id=person.person_id))
|
|
467
|
+
update = CallQueue(agents=details.agents)
|
|
468
|
+
api.telephony.callqueue.update(location_id=loc_id, queue_id=q_id, update=update)
|
|
469
|
+
|
|
470
|
+
# Remove agents
|
|
471
|
+
details.agents = [a for a in details.agents if a.agent_id != target_id]
|
|
472
|
+
update = CallQueue(agents=details.agents)
|
|
473
|
+
api.telephony.callqueue.update(location_id=loc_id, queue_id=q_id, update=update)
|
|
474
|
+
|
|
475
|
+
# Toggle join/unjoin
|
|
476
|
+
for agent in details.agents:
|
|
477
|
+
agent.join_enabled = True # or False
|
|
478
|
+
update = CallQueue(agents=details.agents)
|
|
479
|
+
api.telephony.callqueue.update(location_id=loc_id, queue_id=q_id, update=update)
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
### Call Queue Policy Sub-API
|
|
483
|
+
|
|
484
|
+
**SDK access path:** `api.telephony.callqueue.policy`
|
|
485
|
+
|
|
486
|
+
These are additional routing policies that sit alongside the main queue configuration:
|
|
487
|
+
|
|
488
|
+
#### Holiday Service
|
|
489
|
+
|
|
490
|
+
| Method | Signature |
|
|
491
|
+
|--------|-----------|
|
|
492
|
+
| `holiday_service_details()` | `holiday_service_details(location_id, queue_id, org_id=None) -> HolidayService` |
|
|
493
|
+
| `holiday_service_update()` | `holiday_service_update(location_id, queue_id, update: HolidayService, org_id=None)` |
|
|
494
|
+
|
|
495
|
+
`HolidayService` fields:
|
|
496
|
+
- `holiday_service_enabled`: bool
|
|
497
|
+
- `action`: `CPActionType` -- `BUSY` or `TRANSFER`
|
|
498
|
+
- `holiday_schedule_name` / `holiday_schedule_level`: Which schedule to use (from `holiday_schedules` list)
|
|
499
|
+
- `transfer_phone_number`: Destination when action is TRANSFER
|
|
500
|
+
- `play_announcement_before_enabled`: bool
|
|
501
|
+
- `audio_message_selection`: `Greeting` (DEFAULT/CUSTOM)
|
|
502
|
+
- `audio_files`: `list[AnnAudioFile]`
|
|
503
|
+
- `holiday_schedules`: `list[CQHolidaySchedule]` -- read-only list of available schedules
|
|
504
|
+
|
|
505
|
+
#### Night Service
|
|
506
|
+
|
|
507
|
+
| Method | Signature |
|
|
508
|
+
|--------|-----------|
|
|
509
|
+
| `night_service_detail()` | `night_service_detail(location_id, queue_id, org_id=None) -> NightService` |
|
|
510
|
+
| `night_service_update()` | `night_service_update(location_id, queue_id, update: NightService, org_id=None)` |
|
|
511
|
+
|
|
512
|
+
`NightService` fields:
|
|
513
|
+
- `night_service_enabled`: bool
|
|
514
|
+
- `action`: `CPActionType` -- `BUSY` or `TRANSFER`
|
|
515
|
+
- `transfer_phone_number`: Destination when action is TRANSFER
|
|
516
|
+
- `announcement_mode`: `AnnouncementMode` -- `NORMAL` or `MANUAL`
|
|
517
|
+
- `business_hours_name` / `business_hours_level`: Schedule reference
|
|
518
|
+
- `force_night_service_enabled`: Override business hours
|
|
519
|
+
- Separate `audio_message_selection` / `audio_files` for NORMAL mode and `manual_audio_message_selection` / `manual_audio_files` for MANUAL mode
|
|
520
|
+
|
|
521
|
+
#### Stranded Calls
|
|
522
|
+
|
|
523
|
+
| Method | Signature |
|
|
524
|
+
|--------|-----------|
|
|
525
|
+
| `stranded_calls_details()` | `stranded_calls_details(location_id, queue_id, org_id=None) -> StrandedCalls` |
|
|
526
|
+
| `stranded_calls_update()` | `stranded_calls_update(location_id, queue_id, update: StrandedCalls, org_id=None)` |
|
|
527
|
+
|
|
528
|
+
Handles calls when all agents log off or become unavailable.
|
|
529
|
+
|
|
530
|
+
`StrandedCallsAction` enum:
|
|
531
|
+
| Value | Description |
|
|
532
|
+
|-------|-------------|
|
|
533
|
+
| `NONE` | Calls remain in queue |
|
|
534
|
+
| `BUSY` | Fast-busy tone |
|
|
535
|
+
| `TRANSFER` | Transfer to number |
|
|
536
|
+
| `NIGHT_SERVICE` | Use night service config |
|
|
537
|
+
| `RINGING` | Play ringback until caller hangs up |
|
|
538
|
+
| `ANNOUNCEMENT` | Play announcement in loop |
|
|
539
|
+
|
|
540
|
+
#### Forced Forward
|
|
541
|
+
|
|
542
|
+
| Method | Signature |
|
|
543
|
+
|--------|-----------|
|
|
544
|
+
| `forced_forward_details()` | `forced_forward_details(location_id, queue_id, org_id=None) -> ForcedForward` |
|
|
545
|
+
| `forced_forward_update()` | `forced_forward_update(location_id, queue_id, update: ForcedForward, org_id=None)` |
|
|
546
|
+
|
|
547
|
+
Temporarily diverts all incoming calls to a destination. Calls already in the queue remain queued.
|
|
548
|
+
|
|
549
|
+
`ForcedForward` fields:
|
|
550
|
+
- `forced_forward_enabled`: bool
|
|
551
|
+
- `transfer_phone_number`: Destination
|
|
552
|
+
- `play_announcement_before_enabled`: bool
|
|
553
|
+
- `audio_message_selection`: Greeting
|
|
554
|
+
- `audio_files`: list[AnnAudioFile]
|
|
555
|
+
|
|
556
|
+
### Announcement Files Sub-API
|
|
557
|
+
|
|
558
|
+
**SDK access path:** `api.telephony.callqueue.announcement`
|
|
559
|
+
|
|
560
|
+
| Method | Signature |
|
|
561
|
+
|--------|-----------|
|
|
562
|
+
| `list()` | `list(location_id, queue_id, org_id=None) -> Generator[Announcement]` |
|
|
563
|
+
| `delete_announcement()` | `delete_announcement(location_id, queue_id, file_name, org_id=None)` |
|
|
564
|
+
|
|
565
|
+
`Announcement` model: `name` (alias: `fileName`), `size` (alias: `fileSize`)
|
|
566
|
+
|
|
567
|
+
**Upload is supported via the Announcement Repository API** (`POST /telephony/config/announcements` or `POST /telephony/config/locations/{locationId}/announcements` with multipart/form-data). See [location-calling-media.md](location-calling-media.md) section 1.
|
|
568
|
+
|
|
569
|
+
### Phone Number/Extension Assignment
|
|
570
|
+
|
|
571
|
+
Same pattern as auto attendants:
|
|
572
|
+
- `primary_available_phone_numbers(location_id, ...)`
|
|
573
|
+
- `alternate_available_phone_numbers(location_id, ...)`
|
|
574
|
+
- `call_forward_available_phone_numbers(location_id, ...)`
|
|
575
|
+
|
|
576
|
+
### Org-Level Call Queue Settings
|
|
577
|
+
|
|
578
|
+
`CallQueueSettings` (applies organization-wide):
|
|
579
|
+
|
|
580
|
+
| Field | Type | Notes |
|
|
581
|
+
|-------|------|-------|
|
|
582
|
+
| `maintain_queue_position_for_sim_ring_enabled` | `bool` | Optimized simultaneous ring algorithm |
|
|
583
|
+
| `force_agent_unavailable_on_bounced_enabled` | `bool` | Set agent unavailable on bounced calls |
|
|
584
|
+
| `play_tone_to_agent_for_barge_in_enabled` | `bool` | |
|
|
585
|
+
| `play_tone_to_agent_for_silent_monitoring_enabled` | `bool` | |
|
|
586
|
+
| `play_tone_to_agent_for_supervisor_coaching_enabled` | `bool` | |
|
|
587
|
+
|
|
588
|
+
### Raw HTTP
|
|
589
|
+
<!-- Updated by playbook session 2026-03-18 -->
|
|
590
|
+
|
|
591
|
+
```python
|
|
592
|
+
from wxc_sdk import WebexSimpleApi
|
|
593
|
+
api = WebexSimpleApi() # auth via WEBEX_ACCESS_TOKEN env var
|
|
594
|
+
BASE = "https://webexapis.com/v1"
|
|
595
|
+
```
|
|
596
|
+
|
|
597
|
+
**List call queues:**
|
|
598
|
+
```python
|
|
599
|
+
params = {"locationId": loc_id, "max": 1000}
|
|
600
|
+
result = api.session.rest_get(f"{BASE}/telephony/config/queues", params=params)
|
|
601
|
+
queues = result.get("queues", [])
|
|
602
|
+
# Each item: {"id", "name", "locationId", "locationName", "phoneNumber", "extension", "enabled", ...}
|
|
603
|
+
```
|
|
604
|
+
|
|
605
|
+
**Get details:**
|
|
606
|
+
```python
|
|
607
|
+
cq = api.session.rest_get(f"{BASE}/telephony/config/locations/{loc_id}/queues/{queue_id}")
|
|
608
|
+
```
|
|
609
|
+
|
|
610
|
+
**Create call queue:**
|
|
611
|
+
```python
|
|
612
|
+
body = {
|
|
613
|
+
"name": "Support Queue",
|
|
614
|
+
"extension": "2000",
|
|
615
|
+
"callPolicies": {
|
|
616
|
+
"routingType": "PRIORITY_BASED",
|
|
617
|
+
"policy": "CIRCULAR"
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
result = api.session.rest_post(f"{BASE}/telephony/config/locations/{loc_id}/queues", json=body)
|
|
621
|
+
new_id = result.get("id")
|
|
622
|
+
```
|
|
623
|
+
|
|
624
|
+
Required fields: `name`, `extension` (or `phoneNumber`), `callPolicies` (with `routingType` and `policy`).
|
|
625
|
+
|
|
626
|
+
**Update call queue:**
|
|
627
|
+
```python
|
|
628
|
+
body = {"name": "Updated Queue Name"} # partial update — only changed fields
|
|
629
|
+
api.session.rest_put(f"{BASE}/telephony/config/locations/{loc_id}/queues/{queue_id}", json=body)
|
|
630
|
+
```
|
|
631
|
+
|
|
632
|
+
Gotcha: sending the full details object back on update fails with "Missing callingLineIdPhoneNumber" when `callingLineIdPolicy` is `CUSTOM`. Always use a partial object with only the fields you want to change.
|
|
633
|
+
|
|
634
|
+
**Delete call queue:**
|
|
635
|
+
```python
|
|
636
|
+
api.session.rest_delete(f"{BASE}/telephony/config/locations/{loc_id}/queues/{queue_id}")
|
|
637
|
+
```
|
|
638
|
+
|
|
639
|
+
**Add/remove agents via raw HTTP:**
|
|
640
|
+
```python
|
|
641
|
+
# Get current details, modify agents, send partial update
|
|
642
|
+
cq = api.session.rest_get(f"{BASE}/telephony/config/locations/{loc_id}/queues/{queue_id}")
|
|
643
|
+
agents = cq.get("agents", [])
|
|
644
|
+
agents.append({"id": person_id})
|
|
645
|
+
api.session.rest_put(
|
|
646
|
+
f"{BASE}/telephony/config/locations/{loc_id}/queues/{queue_id}",
|
|
647
|
+
json={"agents": agents}
|
|
648
|
+
)
|
|
649
|
+
```
|
|
650
|
+
|
|
651
|
+
**Call queue policy sub-APIs:**
|
|
652
|
+
```python
|
|
653
|
+
# Holiday service
|
|
654
|
+
hs = api.session.rest_get(f"{BASE}/telephony/config/locations/{loc_id}/queues/{queue_id}/holidayService")
|
|
655
|
+
api.session.rest_put(f"{BASE}/telephony/config/locations/{loc_id}/queues/{queue_id}/holidayService", json=body)
|
|
656
|
+
|
|
657
|
+
# Night service
|
|
658
|
+
ns = api.session.rest_get(f"{BASE}/telephony/config/locations/{loc_id}/queues/{queue_id}/nightService")
|
|
659
|
+
api.session.rest_put(f"{BASE}/telephony/config/locations/{loc_id}/queues/{queue_id}/nightService", json=body)
|
|
660
|
+
|
|
661
|
+
# Stranded calls
|
|
662
|
+
sc = api.session.rest_get(f"{BASE}/telephony/config/locations/{loc_id}/queues/{queue_id}/strandedCalls")
|
|
663
|
+
api.session.rest_put(f"{BASE}/telephony/config/locations/{loc_id}/queues/{queue_id}/strandedCalls", json=body)
|
|
664
|
+
|
|
665
|
+
# Forced forward
|
|
666
|
+
ff = api.session.rest_get(f"{BASE}/telephony/config/locations/{loc_id}/queues/{queue_id}/forcedForward")
|
|
667
|
+
api.session.rest_put(f"{BASE}/telephony/config/locations/{loc_id}/queues/{queue_id}/forcedForward", json=body)
|
|
668
|
+
```
|
|
669
|
+
|
|
670
|
+
**Call forwarding settings:**
|
|
671
|
+
```python
|
|
672
|
+
fwd = api.session.rest_get(
|
|
673
|
+
f"{BASE}/telephony/config/locations/{loc_id}/queues/{queue_id}/callForwarding"
|
|
674
|
+
)
|
|
675
|
+
```
|
|
676
|
+
|
|
677
|
+
### CLI Examples
|
|
678
|
+
|
|
679
|
+
```bash
|
|
680
|
+
# List all call queues (org-wide)
|
|
681
|
+
wxcli call-queue list
|
|
682
|
+
|
|
683
|
+
# List call queues at a specific location
|
|
684
|
+
wxcli call-queue list --location-id Y2lzY29zcGFyazovL...
|
|
685
|
+
|
|
686
|
+
# Filter by name
|
|
687
|
+
wxcli call-queue list --name "Support Queue"
|
|
688
|
+
|
|
689
|
+
# Get details for a specific call queue
|
|
690
|
+
wxcli call-queue show Y2lzY29zcGFyazovL_LOC_ID Y2lzY29zcGFyazovL_QUEUE_ID
|
|
691
|
+
|
|
692
|
+
# Create a basic call queue
|
|
693
|
+
wxcli call-queue create Y2lzY29zcGFyazovL_LOC_ID \
|
|
694
|
+
--name "Support Queue" \
|
|
695
|
+
--extension "2000"
|
|
696
|
+
|
|
697
|
+
# Create a call queue with agents and routing policy via --json-body
|
|
698
|
+
wxcli call-queue create Y2lzY29zcGFyazovL_LOC_ID --json-body '{
|
|
699
|
+
"name": "Support Queue",
|
|
700
|
+
"extension": "2000",
|
|
701
|
+
"callPolicies": {
|
|
702
|
+
"routingType": "PRIORITY_BASED",
|
|
703
|
+
"policy": "CIRCULAR"
|
|
704
|
+
},
|
|
705
|
+
"queueSettings": {
|
|
706
|
+
"queueSize": 15,
|
|
707
|
+
"overflow": {
|
|
708
|
+
"action": "PERFORM_BUSY_TREATMENT"
|
|
709
|
+
}
|
|
710
|
+
},
|
|
711
|
+
"agents": [
|
|
712
|
+
{"id": "PERSON_ID_1"},
|
|
713
|
+
{"id": "PERSON_ID_2"}
|
|
714
|
+
]
|
|
715
|
+
}'
|
|
716
|
+
|
|
717
|
+
# Update basic fields
|
|
718
|
+
wxcli call-queue update Y2lzY29zcGFyazovL_LOC_ID Y2lzY29zcGFyazovL_QUEUE_ID \
|
|
719
|
+
--name "Renamed Queue" --enabled
|
|
720
|
+
|
|
721
|
+
# Update agents or complex settings via --json-body (partial update)
|
|
722
|
+
wxcli call-queue update Y2lzY29zcGFyazovL_LOC_ID Y2lzY29zcGFyazovL_QUEUE_ID --json-body '{
|
|
723
|
+
"agents": [
|
|
724
|
+
{"id": "PERSON_ID_1"},
|
|
725
|
+
{"id": "PERSON_ID_2"},
|
|
726
|
+
{"id": "PERSON_ID_3"}
|
|
727
|
+
]
|
|
728
|
+
}'
|
|
729
|
+
|
|
730
|
+
# Delete a call queue
|
|
731
|
+
wxcli call-queue delete Y2lzY29zcGFyazovL_LOC_ID Y2lzY29zcGFyazovL_QUEUE_ID --force
|
|
732
|
+
|
|
733
|
+
# List all call queue agents (org-wide or filtered)
|
|
734
|
+
wxcli call-queue list-agents
|
|
735
|
+
wxcli call-queue list-agents --queue-id Y2lzY29zcGFyazovL_QUEUE_ID
|
|
736
|
+
|
|
737
|
+
# Get call forwarding settings
|
|
738
|
+
wxcli call-queue show-call-forwarding Y2lzY29zcGFyazovL_LOC_ID Y2lzY29zcGFyazovL_QUEUE_ID
|
|
739
|
+
|
|
740
|
+
# View holiday service settings
|
|
741
|
+
wxcli call-queue list-holiday-service Y2lzY29zcGFyazovL_LOC_ID Y2lzY29zcGFyazovL_QUEUE_ID
|
|
742
|
+
|
|
743
|
+
# View night service, stranded calls, forced forward
|
|
744
|
+
wxcli call-queue list-night-service Y2lzY29zcGFyazovL_LOC_ID Y2lzY29zcGFyazovL_QUEUE_ID
|
|
745
|
+
wxcli call-queue list-stranded-calls Y2lzY29zcGFyazovL_LOC_ID Y2lzY29zcGFyazovL_QUEUE_ID
|
|
746
|
+
wxcli call-queue list-forced-forward Y2lzY29zcGFyazovL_LOC_ID Y2lzY29zcGFyazovL_QUEUE_ID
|
|
747
|
+
|
|
748
|
+
# List available agents for a location
|
|
749
|
+
wxcli call-queue list-available-agents-queues --location-id Y2lzY29zcGFyazovL_LOC_ID
|
|
750
|
+
```
|
|
751
|
+
|
|
752
|
+
---
|
|
753
|
+
|
|
754
|
+
## 3. Hunt Groups
|
|
755
|
+
|
|
756
|
+
### Overview
|
|
757
|
+
|
|
758
|
+
Hunt groups route incoming calls to a group of people or workspaces using a configurable ring pattern. Unlike call queues, hunt groups do not hold calls in a queue -- they ring agents directly according to the routing policy, and if no one answers, the call follows no-answer/busy redirect rules.
|
|
759
|
+
|
|
760
|
+
Use a hunt group when calls should ring agents directly without queuing (small teams, on-call groups).
|
|
761
|
+
|
|
762
|
+
**SDK access path:** `api.telephony.huntgroup`
|
|
763
|
+
|
|
764
|
+
### API Operations
|
|
765
|
+
|
|
766
|
+
| Operation | Method | Signature |
|
|
767
|
+
|-----------|--------|-----------|
|
|
768
|
+
| **List** | `list()` | `list(org_id=None, location_id=None, name=None, phone_number=None, **params) -> Generator[HuntGroup]` |
|
|
769
|
+
| **Get by name** | `by_name()` | `by_name(name, location_id=None, org_id=None) -> Optional[HuntGroup]` |
|
|
770
|
+
| **Get details** | `details()` | `details(location_id, huntgroup_id, org_id=None) -> HuntGroup` |
|
|
771
|
+
| **Create** | `create()` | `create(location_id, settings: HuntGroup, org_id=None) -> str` |
|
|
772
|
+
| **Update** | `update()` | `update(location_id, huntgroup_id, update: HuntGroup, org_id=None) -> None` |
|
|
773
|
+
| **Delete** | `delete_huntgroup()` | `delete_huntgroup(location_id, huntgroup_id, org_id=None) -> None` |
|
|
774
|
+
|
|
775
|
+
### Key Data Models
|
|
776
|
+
|
|
777
|
+
#### `HuntGroup` (extends `HGandCQ`)
|
|
778
|
+
|
|
779
|
+
| Field | Type | Required for Create | Notes |
|
|
780
|
+
|-------|------|:-------------------:|-------|
|
|
781
|
+
| `name` | `str` | Yes | Unique name |
|
|
782
|
+
| `phone_number` | `str` | One of phone_number/extension | |
|
|
783
|
+
| `extension` | `str` | One of phone_number/extension | |
|
|
784
|
+
| `agents` | `list[Agent]` | No | Empty by default on creation |
|
|
785
|
+
| `call_policies` | `HGCallPolicies` | No | Auto-defaulted to CIRCULAR if not provided |
|
|
786
|
+
| `enabled` | `bool` | No | |
|
|
787
|
+
| `language_code` | `str` | No | |
|
|
788
|
+
| `time_zone` | `str` | No | |
|
|
789
|
+
| `alternate_numbers` | `list[AlternateNumber]` | No | Up to 10 |
|
|
790
|
+
| `hunt_group_caller_id_for_outgoing_calls_enabled` | `bool` | No | Use hunt group as outbound caller ID |
|
|
791
|
+
|
|
792
|
+
**Convenience constructor:**
|
|
793
|
+
```python
|
|
794
|
+
HuntGroup.create(name="Sales Team",
|
|
795
|
+
extension="3000")
|
|
796
|
+
# Creates a minimal hunt group with no agents.
|
|
797
|
+
# call_policies defaults to CIRCULAR on API create().
|
|
798
|
+
```
|
|
799
|
+
|
|
800
|
+
#### `HGCallPolicies`
|
|
801
|
+
|
|
802
|
+
| Field | Type | Default | Notes |
|
|
803
|
+
|-------|------|---------|-------|
|
|
804
|
+
| `policy` | `Policy` | `CIRCULAR` | Same Policy enum as call queues |
|
|
805
|
+
| `waiting_enabled` | `bool` | `False` | If false, acts as "advance when busy" -- skips agents on a call |
|
|
806
|
+
| `group_busy_enabled` | `bool` | No default | Set hunt group to busy status; all new calls get busy treatment |
|
|
807
|
+
| `allow_members_to_control_group_busy_enabled` | `bool` | No default | Let agents toggle group busy |
|
|
808
|
+
| `no_answer` | `NoAnswer` | See below | What happens when no agent answers |
|
|
809
|
+
| `busy_redirect` | `BusinessContinuity` | See below | Where to send calls when all agents busy or group is busy |
|
|
810
|
+
| `business_continuity_redirect` | `BusinessContinuity` | See below | Fallback when phone disconnected (power outage, etc.) |
|
|
811
|
+
|
|
812
|
+
#### `NoAnswer`
|
|
813
|
+
|
|
814
|
+
| Field | Type | Default | Notes |
|
|
815
|
+
|-------|------|---------|-------|
|
|
816
|
+
| `next_agent_enabled` | `bool` | `False` | Advance to next agent after rings |
|
|
817
|
+
| `next_agent_rings` | `int` | `5` | Rings before advancing |
|
|
818
|
+
| `forward_enabled` | `bool` | `False` | Forward unanswered calls |
|
|
819
|
+
| `destination` | `str` | None | Forward-to number |
|
|
820
|
+
| `number_of_rings` | `int` | `15` | Rings before forwarding |
|
|
821
|
+
| `system_max_number_of_rings` | `int` | `20` | Read-only system maximum |
|
|
822
|
+
| `destination_voicemail_enabled` | `bool` | `False` | Send to destination's voicemail (prefixes `*55`) |
|
|
823
|
+
|
|
824
|
+
#### `BusinessContinuity`
|
|
825
|
+
|
|
826
|
+
| Field | Type | Default | Notes |
|
|
827
|
+
|-------|------|---------|-------|
|
|
828
|
+
| `enabled` | `bool` | `False` | |
|
|
829
|
+
| `destination` | `str` | None | Redirect target |
|
|
830
|
+
| `destination_voicemail_enabled` | `bool` | `False` | |
|
|
831
|
+
|
|
832
|
+
### Agent/Member Management
|
|
833
|
+
|
|
834
|
+
Hunt group agents use the same `Agent` model as call queues. To modify agents, update the hunt group with the new agent list:
|
|
835
|
+
|
|
836
|
+
```python
|
|
837
|
+
hg = api.telephony.huntgroup.details(location_id=loc_id, huntgroup_id=hg_id)
|
|
838
|
+
hg.agents.append(Agent(agent_id=new_person_id))
|
|
839
|
+
api.telephony.huntgroup.update(location_id=loc_id, huntgroup_id=hg_id, update=hg)
|
|
840
|
+
```
|
|
841
|
+
|
|
842
|
+
**Key difference from call queues:** Hunt groups do not have a `join_enabled` toggle on agents. All agents in the group receive calls (subject to the `waiting_enabled` setting).
|
|
843
|
+
|
|
844
|
+
### Phone Number/Extension Assignment
|
|
845
|
+
|
|
846
|
+
- `primary_available_phone_numbers(location_id, ...)`
|
|
847
|
+
- `alternate_available_phone_numbers(location_id, ...)`
|
|
848
|
+
- `forward_available_phone_numbers(location_id, ...)` -- note the method name differs slightly from CQ/AA
|
|
849
|
+
|
|
850
|
+
### Forwarding
|
|
851
|
+
|
|
852
|
+
Hunt groups have a `forwarding` sub-API (instance of `ForwardingApi` with `FeatureSelector.huntgroups`). See [Shared Forwarding API](#4-shared-forwarding-api).
|
|
853
|
+
|
|
854
|
+
### Raw HTTP
|
|
855
|
+
<!-- Updated by playbook session 2026-03-18 -->
|
|
856
|
+
|
|
857
|
+
```python
|
|
858
|
+
from wxc_sdk import WebexSimpleApi
|
|
859
|
+
api = WebexSimpleApi() # auth via WEBEX_ACCESS_TOKEN env var
|
|
860
|
+
BASE = "https://webexapis.com/v1"
|
|
861
|
+
```
|
|
862
|
+
|
|
863
|
+
**List hunt groups:**
|
|
864
|
+
```python
|
|
865
|
+
params = {"locationId": loc_id, "max": 1000}
|
|
866
|
+
result = api.session.rest_get(f"{BASE}/telephony/config/huntGroups", params=params)
|
|
867
|
+
hgs = result.get("huntGroups", [])
|
|
868
|
+
# Each item: {"id", "name", "locationId", "locationName", "phoneNumber", "extension", "enabled", ...}
|
|
869
|
+
```
|
|
870
|
+
|
|
871
|
+
**Get details:**
|
|
872
|
+
```python
|
|
873
|
+
hg = api.session.rest_get(f"{BASE}/telephony/config/locations/{loc_id}/huntGroups/{hg_id}")
|
|
874
|
+
```
|
|
875
|
+
|
|
876
|
+
**Create hunt group:**
|
|
877
|
+
```python
|
|
878
|
+
body = {
|
|
879
|
+
"name": "Sales Team",
|
|
880
|
+
"extension": "3000"
|
|
881
|
+
}
|
|
882
|
+
result = api.session.rest_post(f"{BASE}/telephony/config/locations/{loc_id}/huntGroups", json=body)
|
|
883
|
+
new_id = result.get("id")
|
|
884
|
+
```
|
|
885
|
+
|
|
886
|
+
Required fields: `name`, `extension` (or `phoneNumber`). `callPolicies` defaults to `CIRCULAR` if not provided. Agents are optional at creation -- can be added later via update.
|
|
887
|
+
|
|
888
|
+
**Update hunt group:**
|
|
889
|
+
```python
|
|
890
|
+
body = {"name": "Updated Team Name"} # partial update — only changed fields
|
|
891
|
+
api.session.rest_put(f"{BASE}/telephony/config/locations/{loc_id}/huntGroups/{hg_id}", json=body)
|
|
892
|
+
```
|
|
893
|
+
|
|
894
|
+
**Delete hunt group:**
|
|
895
|
+
```python
|
|
896
|
+
api.session.rest_delete(f"{BASE}/telephony/config/locations/{loc_id}/huntGroups/{hg_id}")
|
|
897
|
+
```
|
|
898
|
+
|
|
899
|
+
**Add/remove agents via raw HTTP:**
|
|
900
|
+
```python
|
|
901
|
+
hg = api.session.rest_get(f"{BASE}/telephony/config/locations/{loc_id}/huntGroups/{hg_id}")
|
|
902
|
+
agents = hg.get("agents", [])
|
|
903
|
+
agents.append({"id": person_id})
|
|
904
|
+
api.session.rest_put(
|
|
905
|
+
f"{BASE}/telephony/config/locations/{loc_id}/huntGroups/{hg_id}",
|
|
906
|
+
json={"agents": agents}
|
|
907
|
+
)
|
|
908
|
+
```
|
|
909
|
+
|
|
910
|
+
**Call forwarding settings:**
|
|
911
|
+
```python
|
|
912
|
+
fwd = api.session.rest_get(
|
|
913
|
+
f"{BASE}/telephony/config/locations/{loc_id}/huntGroups/{hg_id}/callForwarding"
|
|
914
|
+
)
|
|
915
|
+
```
|
|
916
|
+
|
|
917
|
+
### CLI Examples
|
|
918
|
+
|
|
919
|
+
```bash
|
|
920
|
+
# List all hunt groups (org-wide)
|
|
921
|
+
wxcli hunt-group list
|
|
922
|
+
|
|
923
|
+
# List hunt groups at a specific location
|
|
924
|
+
wxcli hunt-group list --location-id Y2lzY29zcGFyazovL...
|
|
925
|
+
|
|
926
|
+
# Filter by name
|
|
927
|
+
wxcli hunt-group list --name "Sales Team"
|
|
928
|
+
|
|
929
|
+
# Get details for a specific hunt group
|
|
930
|
+
wxcli hunt-group show Y2lzY29zcGFyazovL_LOC_ID Y2lzY29zcGFyazovL_HG_ID
|
|
931
|
+
|
|
932
|
+
# Create a basic hunt group
|
|
933
|
+
wxcli hunt-group create Y2lzY29zcGFyazovL_LOC_ID \
|
|
934
|
+
--name "Sales Team" \
|
|
935
|
+
--extension "3000" \
|
|
936
|
+
--enabled
|
|
937
|
+
|
|
938
|
+
# Create with agents and call policies via --json-body
|
|
939
|
+
wxcli hunt-group create Y2lzY29zcGFyazovL_LOC_ID --json-body '{
|
|
940
|
+
"name": "Sales Team",
|
|
941
|
+
"extension": "3000",
|
|
942
|
+
"enabled": true,
|
|
943
|
+
"callPolicies": {
|
|
944
|
+
"policy": "SIMULTANEOUS",
|
|
945
|
+
"noAnswer": {
|
|
946
|
+
"nextAgentEnabled": true,
|
|
947
|
+
"nextAgentRings": 3,
|
|
948
|
+
"forwardEnabled": true,
|
|
949
|
+
"destination": "+15551234567",
|
|
950
|
+
"numberOfRings": 10
|
|
951
|
+
}
|
|
952
|
+
},
|
|
953
|
+
"agents": [
|
|
954
|
+
{"id": "PERSON_ID_1"},
|
|
955
|
+
{"id": "PERSON_ID_2"}
|
|
956
|
+
]
|
|
957
|
+
}'
|
|
958
|
+
|
|
959
|
+
# Update basic fields
|
|
960
|
+
wxcli hunt-group update Y2lzY29zcGFyazovL_LOC_ID Y2lzY29zcGFyazovL_HG_ID \
|
|
961
|
+
--name "Renamed Team" --enabled
|
|
962
|
+
|
|
963
|
+
# Update agents via --json-body (partial update)
|
|
964
|
+
wxcli hunt-group update Y2lzY29zcGFyazovL_LOC_ID Y2lzY29zcGFyazovL_HG_ID --json-body '{
|
|
965
|
+
"agents": [
|
|
966
|
+
{"id": "PERSON_ID_1"},
|
|
967
|
+
{"id": "PERSON_ID_2"},
|
|
968
|
+
{"id": "PERSON_ID_3"}
|
|
969
|
+
]
|
|
970
|
+
}'
|
|
971
|
+
|
|
972
|
+
# Delete a hunt group
|
|
973
|
+
wxcli hunt-group delete Y2lzY29zcGFyazovL_LOC_ID Y2lzY29zcGFyazovL_HG_ID --force
|
|
974
|
+
|
|
975
|
+
# Get call forwarding settings
|
|
976
|
+
wxcli hunt-group show-call-forwarding Y2lzY29zcGFyazovL_LOC_ID Y2lzY29zcGFyazovL_HG_ID
|
|
977
|
+
|
|
978
|
+
# Create a selective call forwarding rule
|
|
979
|
+
wxcli hunt-group create-selective-rules Y2lzY29zcGFyazovL_LOC_ID Y2lzY29zcGFyazovL_HG_ID --json-body '{
|
|
980
|
+
"name": "After Hours Rule",
|
|
981
|
+
"enabled": true,
|
|
982
|
+
"businessSchedule": "Business Hours",
|
|
983
|
+
"forwardTo": {"selection": "FORWARD_TO_SPECIFIED_NUMBER", "phoneNumber": "+15559876543"},
|
|
984
|
+
"callsFrom": {"selection": "ANY"},
|
|
985
|
+
"callsTo": {"selection": "ANY"}
|
|
986
|
+
}'
|
|
987
|
+
```
|
|
988
|
+
|
|
989
|
+
---
|
|
990
|
+
|
|
991
|
+
## 4. Shared Forwarding API
|
|
992
|
+
|
|
993
|
+
All three features (auto attendants, call queues, hunt groups) share the same `ForwardingApi` class, instantiated with a different `FeatureSelector`.
|
|
994
|
+
|
|
995
|
+
**SDK access paths:**
|
|
996
|
+
- `api.telephony.auto_attendant.forwarding`
|
|
997
|
+
- `api.telephony.callqueue.forwarding`
|
|
998
|
+
- `api.telephony.huntgroup.forwarding`
|
|
999
|
+
|
|
1000
|
+
### API Endpoints
|
|
1001
|
+
|
|
1002
|
+
Base: `telephony/config/locations/{locationId}/{feature}/{featureId}/callForwarding`
|
|
1003
|
+
|
|
1004
|
+
| Method | Signature | Notes |
|
|
1005
|
+
|--------|-----------|-------|
|
|
1006
|
+
| `settings()` | `settings(location_id, feature_id, org_id=None) -> CallForwarding` | Get forwarding settings |
|
|
1007
|
+
| `update()` | `update(location_id, feature_id, forwarding: CallForwarding, org_id=None)` | Update forwarding settings |
|
|
1008
|
+
| `create_call_forwarding_rule()` | `create_call_forwarding_rule(location_id, feature_id, forwarding_rule: ForwardingRuleDetails, org_id=None) -> str` | Create selective rule; returns rule ID |
|
|
1009
|
+
| `call_forwarding_rule()` | `call_forwarding_rule(location_id, feature_id, rule_id, org_id=None) -> ForwardingRuleDetails` | Get rule details |
|
|
1010
|
+
| `update_call_forwarding_rule()` | `update_call_forwarding_rule(location_id, feature_id, rule_id, forwarding_rule: ForwardingRuleDetails, org_id=None) -> str` | Update rule; **rule ID changes if name changes** |
|
|
1011
|
+
| `delete_call_forwarding_rule()` | `delete_call_forwarding_rule(location_id, feature_id, rule_id, org_id=None)` | Delete a selective rule |
|
|
1012
|
+
| `switch_mode_for_call_forwarding()` | `switch_mode_for_call_forwarding(location_id, feature_id, org_id=None)` | Switch to normal operating mode |
|
|
1013
|
+
|
|
1014
|
+
### Key Data Models
|
|
1015
|
+
|
|
1016
|
+
#### `CallForwarding`
|
|
1017
|
+
|
|
1018
|
+
| Field | Type | Notes |
|
|
1019
|
+
|-------|------|-------|
|
|
1020
|
+
| `always` | `ForwardingSetting` | Forward all calls unconditionally |
|
|
1021
|
+
| `selective` | `ForwardingSetting` | Forward based on rules |
|
|
1022
|
+
| `rules` | `list[ForwardingRule]` | Summary list of selective rules |
|
|
1023
|
+
| `operating_modes` | `ForwardOperatingModes` | Mode-based forwarding |
|
|
1024
|
+
|
|
1025
|
+
#### `ForwardingSetting`
|
|
1026
|
+
|
|
1027
|
+
| Field | Type | Notes |
|
|
1028
|
+
|-------|------|-------|
|
|
1029
|
+
| `enabled` | `bool` | |
|
|
1030
|
+
| `destination` | `str` | Forward-to number |
|
|
1031
|
+
| `ring_reminder_enabled` | `bool` | Brief tone on agent's phone |
|
|
1032
|
+
| `destination_voice_mail_enabled` | `bool` | Send to voicemail if destination is internal with VM |
|
|
1033
|
+
|
|
1034
|
+
#### `ForwardingRuleDetails`
|
|
1035
|
+
|
|
1036
|
+
| Field | Type | Notes |
|
|
1037
|
+
|-------|------|-------|
|
|
1038
|
+
| `name` | `str` | Rule name |
|
|
1039
|
+
| `id` | `str` | Rule ID (read-only, changes on name update) |
|
|
1040
|
+
| `enabled` | `bool` | |
|
|
1041
|
+
| `holiday_schedule` | `str` | Schedule name for holiday-based rules |
|
|
1042
|
+
| `business_schedule` | `str` | Schedule name for business-hours rules |
|
|
1043
|
+
| `forward_to` | `ForwardTo` | `FORWARD_TO_DEFAULT_NUMBER`, `FORWARD_TO_SPECIFIED_NUMBER`, or `DO_NOT_FORWARD` |
|
|
1044
|
+
| `calls_to` | `ForwardCallsTo` | Which incoming numbers trigger the rule |
|
|
1045
|
+
| `calls_from` | `CallsFrom` | `ANY` or `CUSTOM` with specific numbers |
|
|
1046
|
+
|
|
1047
|
+
### Raw HTTP
|
|
1048
|
+
<!-- Updated by playbook session 2026-03-18 -->
|
|
1049
|
+
|
|
1050
|
+
The forwarding URL pattern is the same for all three features -- substitute the feature path segment:
|
|
1051
|
+
|
|
1052
|
+
| Feature | Path segment |
|
|
1053
|
+
|---------|-------------|
|
|
1054
|
+
| Auto Attendant | `autoAttendants` |
|
|
1055
|
+
| Call Queue | `queues` |
|
|
1056
|
+
| Hunt Group | `huntGroups` |
|
|
1057
|
+
|
|
1058
|
+
```python
|
|
1059
|
+
BASE = "https://webexapis.com/v1"
|
|
1060
|
+
feature = "autoAttendants" # or "queues" or "huntGroups"
|
|
1061
|
+
feature_id = aa_id # or queue_id or hg_id
|
|
1062
|
+
|
|
1063
|
+
# Get forwarding settings
|
|
1064
|
+
fwd = api.session.rest_get(
|
|
1065
|
+
f"{BASE}/telephony/config/locations/{loc_id}/{feature}/{feature_id}/callForwarding"
|
|
1066
|
+
)
|
|
1067
|
+
|
|
1068
|
+
# Update forwarding settings
|
|
1069
|
+
api.session.rest_put(
|
|
1070
|
+
f"{BASE}/telephony/config/locations/{loc_id}/{feature}/{feature_id}/callForwarding",
|
|
1071
|
+
json={"always": {"enabled": True, "destination": "+15551234567"}}
|
|
1072
|
+
)
|
|
1073
|
+
|
|
1074
|
+
# Create selective forwarding rule
|
|
1075
|
+
rule_body = {
|
|
1076
|
+
"name": "After Hours Rule",
|
|
1077
|
+
"enabled": True,
|
|
1078
|
+
"businessSchedule": "Business Hours",
|
|
1079
|
+
"forwardTo": {"selection": "FORWARD_TO_SPECIFIED_NUMBER", "phoneNumber": "+15559876543"},
|
|
1080
|
+
"callsFrom": {"selection": "ANY"},
|
|
1081
|
+
"callsTo": {"selection": "ANY"}
|
|
1082
|
+
}
|
|
1083
|
+
result = api.session.rest_post(
|
|
1084
|
+
f"{BASE}/telephony/config/locations/{loc_id}/{feature}/{feature_id}/callForwarding/selectiveRules",
|
|
1085
|
+
json=rule_body
|
|
1086
|
+
)
|
|
1087
|
+
rule_id = result.get("id")
|
|
1088
|
+
|
|
1089
|
+
# Get / update / delete a selective rule
|
|
1090
|
+
rule = api.session.rest_get(
|
|
1091
|
+
f"{BASE}/telephony/config/locations/{loc_id}/{feature}/{feature_id}/callForwarding/selectiveRules/{rule_id}"
|
|
1092
|
+
)
|
|
1093
|
+
api.session.rest_put(
|
|
1094
|
+
f"{BASE}/telephony/config/locations/{loc_id}/{feature}/{feature_id}/callForwarding/selectiveRules/{rule_id}",
|
|
1095
|
+
json={"enabled": False}
|
|
1096
|
+
)
|
|
1097
|
+
api.session.rest_delete(
|
|
1098
|
+
f"{BASE}/telephony/config/locations/{loc_id}/{feature}/{feature_id}/callForwarding/selectiveRules/{rule_id}"
|
|
1099
|
+
)
|
|
1100
|
+
```
|
|
1101
|
+
|
|
1102
|
+
Gotcha: when you update a selective rule's `name`, the rule ID changes. The update response returns the new ID.
|
|
1103
|
+
|
|
1104
|
+
### CLI Examples
|
|
1105
|
+
|
|
1106
|
+
The forwarding commands follow the same pattern across all three features. Substitute the feature command group (`auto-attendant`, `call-queue`, or `hunt-group`).
|
|
1107
|
+
|
|
1108
|
+
```bash
|
|
1109
|
+
# Get call forwarding settings (same pattern for all three features)
|
|
1110
|
+
wxcli auto-attendant show-call-forwarding LOC_ID AA_ID
|
|
1111
|
+
wxcli call-queue show-call-forwarding LOC_ID QUEUE_ID
|
|
1112
|
+
wxcli hunt-group show-call-forwarding LOC_ID HG_ID
|
|
1113
|
+
|
|
1114
|
+
# Update call forwarding — enable always-forward via --json-body
|
|
1115
|
+
wxcli auto-attendant update-call-forwarding LOC_ID AA_ID --json-body '{
|
|
1116
|
+
"always": {"enabled": true, "destination": "+15551234567"}
|
|
1117
|
+
}'
|
|
1118
|
+
|
|
1119
|
+
wxcli call-queue update-call-forwarding LOC_ID QUEUE_ID --json-body '{
|
|
1120
|
+
"always": {"enabled": true, "destination": "+15551234567"}
|
|
1121
|
+
}'
|
|
1122
|
+
|
|
1123
|
+
wxcli hunt-group update-call-forwarding LOC_ID HG_ID --json-body '{
|
|
1124
|
+
"always": {"enabled": true, "destination": "+15551234567"}
|
|
1125
|
+
}'
|
|
1126
|
+
|
|
1127
|
+
# Create a selective forwarding rule
|
|
1128
|
+
wxcli auto-attendant create-selective-rules LOC_ID AA_ID \
|
|
1129
|
+
--name "After Hours Rule" --enabled --business-schedule "Business Hours"
|
|
1130
|
+
|
|
1131
|
+
# Create a selective rule with full config via --json-body
|
|
1132
|
+
wxcli call-queue create-selective-rules LOC_ID QUEUE_ID --json-body '{
|
|
1133
|
+
"name": "Holiday Redirect",
|
|
1134
|
+
"enabled": true,
|
|
1135
|
+
"holidaySchedule": "Company Holidays",
|
|
1136
|
+
"forwardTo": {"selection": "FORWARD_TO_SPECIFIED_NUMBER", "phoneNumber": "+15559876543"},
|
|
1137
|
+
"callsFrom": {"selection": "ANY"},
|
|
1138
|
+
"callsTo": {"selection": "ANY"}
|
|
1139
|
+
}'
|
|
1140
|
+
|
|
1141
|
+
# Get, update, and delete selective rules
|
|
1142
|
+
wxcli hunt-group show-selective-rules LOC_ID HG_ID RULE_ID
|
|
1143
|
+
wxcli hunt-group update-selective-rules LOC_ID HG_ID RULE_ID --json-body '{"enabled": false}'
|
|
1144
|
+
wxcli hunt-group delete-selective-rules LOC_ID HG_ID RULE_ID --force
|
|
1145
|
+
|
|
1146
|
+
# Switch to normal operating mode
|
|
1147
|
+
wxcli auto-attendant switch-mode-for LOC_ID AA_ID
|
|
1148
|
+
wxcli call-queue switch-mode-for LOC_ID QUEUE_ID
|
|
1149
|
+
wxcli hunt-group switch-mode-for LOC_ID HG_ID
|
|
1150
|
+
```
|
|
1151
|
+
|
|
1152
|
+
---
|
|
1153
|
+
|
|
1154
|
+
## 5. Common Data Models (HG/CQ Base)
|
|
1155
|
+
|
|
1156
|
+
`HGandCQ` is the shared base class for both `CallQueue` and `HuntGroup`.
|
|
1157
|
+
|
|
1158
|
+
### `HGandCQ` Fields
|
|
1159
|
+
|
|
1160
|
+
| Field | Type | Notes |
|
|
1161
|
+
|-------|------|-------|
|
|
1162
|
+
| `name` | `str` | |
|
|
1163
|
+
| `id` | `str` | Read-only |
|
|
1164
|
+
| `location_name` | `str` | Only from `list()` |
|
|
1165
|
+
| `location_id` | `str` | Only from `list()` |
|
|
1166
|
+
| `phone_number` | `str` | Primary number |
|
|
1167
|
+
| `extension` | `str` | |
|
|
1168
|
+
| `routing_prefix` | `str` | Location routing prefix |
|
|
1169
|
+
| `esn` | `str` | Routing prefix + extension |
|
|
1170
|
+
| `calling_line_id_policy` | `CallingLineIdPolicy` | `DIRECT_LINE`, `LOCATION_NUMBER`, or `CUSTOM` |
|
|
1171
|
+
| `calling_line_id_phone_number` | `str` | Shown when policy is CUSTOM |
|
|
1172
|
+
| `alternate_number_settings` | `AlternateNumberSettings` | Up to 10 alternate numbers with distinctive ring |
|
|
1173
|
+
| `enabled` | `bool` | |
|
|
1174
|
+
| `toll_free_number` | `bool` | Read-only |
|
|
1175
|
+
| `language` / `language_code` | `str` | |
|
|
1176
|
+
| `first_name` / `last_name` | `str` | Caller ID display names |
|
|
1177
|
+
| `time_zone` | `str` | |
|
|
1178
|
+
| `agents` | `list[Agent]` | |
|
|
1179
|
+
| `direct_line_caller_id_name` | `DirectLineCallerIdName` | |
|
|
1180
|
+
| `dial_by_name` | `str` | |
|
|
1181
|
+
|
|
1182
|
+
### `AlternateNumberSettings`
|
|
1183
|
+
|
|
1184
|
+
| Field | Type | Notes |
|
|
1185
|
+
|-------|------|-------|
|
|
1186
|
+
| `distinctive_ring_enabled` | `bool` | Default: True |
|
|
1187
|
+
| `alternate_numbers` | `list[AlternateNumber]` | Up to 10 numbers |
|
|
1188
|
+
|
|
1189
|
+
### `Agent`
|
|
1190
|
+
|
|
1191
|
+
| Field | Type | Notes |
|
|
1192
|
+
|-------|------|-------|
|
|
1193
|
+
| `agent_id` (alias: `id`) | `str` | Person, workspace, or virtual line ID |
|
|
1194
|
+
| `phone_number` | `str` | Read-only in responses |
|
|
1195
|
+
| `extension` | `str` | Read-only in responses |
|
|
1196
|
+
| `weight` | `str` | Only for WEIGHTED policy |
|
|
1197
|
+
| `skill_level` | `int` | Only for SKILL_BASED routing |
|
|
1198
|
+
| `join_enabled` | `bool` | Call queues only |
|
|
1199
|
+
| `location` | `IdAndName` | Read-only |
|
|
1200
|
+
| `has_cx_essentials` | `bool` | Read-only |
|
|
1201
|
+
|
|
1202
|
+
When creating/updating, only `agent_id` is required. Set `weight` or `skill_level` as needed for the routing policy.
|
|
1203
|
+
|
|
1204
|
+
---
|
|
1205
|
+
|
|
1206
|
+
## 6. Required Scopes
|
|
1207
|
+
|
|
1208
|
+
| Operation | Scope |
|
|
1209
|
+
|-----------|-------|
|
|
1210
|
+
| Read (list, details, settings) | `spark-admin:telephony_config_read` |
|
|
1211
|
+
| Write (create, update, delete) | `spark-admin:telephony_config_write` |
|
|
1212
|
+
|
|
1213
|
+
- **Full administrator** or **read-only administrator** tokens work for read operations.
|
|
1214
|
+
- **Full administrator** or **location administrator** tokens are required for write operations.
|
|
1215
|
+
- A **partner administrator** can use the `orgId` query parameter to manage customer organizations.
|
|
1216
|
+
|
|
1217
|
+
---
|
|
1218
|
+
|
|
1219
|
+
## 7. Dependencies
|
|
1220
|
+
|
|
1221
|
+
### Prerequisites for All Three Features
|
|
1222
|
+
|
|
1223
|
+
1. **Location must exist** -- all features are scoped to a location (`location_id` is required for create/details/update/delete).
|
|
1224
|
+
2. **Phone number or extension** -- at least one must be provided at creation. Numbers must be unassigned and associated with the target location. Use the `primary_available_phone_numbers()` method to find candidates.
|
|
1225
|
+
3. **Schedules** -- auto attendants require a `business_schedule` at creation. Call queue holiday/night service policies reference named schedules that must already exist at the org or location level.
|
|
1226
|
+
|
|
1227
|
+
### Call Queue Specific
|
|
1228
|
+
|
|
1229
|
+
4. **Agents** -- must be existing people, workspaces, or virtual lines. Users with Webex Calling Standard license are excluded from available agents.
|
|
1230
|
+
5. **Queue size** -- must be specified either via `queue_size` parameter or a `QueueSettings` object.
|
|
1231
|
+
6. **Customer Assist** -- if creating a Customer Assist (formerly CX Essentials) queue, agents must have the Customer Assist license.
|
|
1232
|
+
|
|
1233
|
+
### Hunt Group Specific
|
|
1234
|
+
|
|
1235
|
+
7. **Agents** -- same types as call queues (people, workspaces, virtual lines). A hunt group can be created with no agents and agents added later.
|
|
1236
|
+
|
|
1237
|
+
### Auto Attendant Specific
|
|
1238
|
+
|
|
1239
|
+
8. **Audio files** -- custom greetings require announcement audio files uploaded via the Announcement Repository API (`POST /telephony/config/announcements` with multipart/form-data). See [location-calling-media.md](location-calling-media.md) section 1 for upload details. WAV and WMA formats supported.
|
|
1240
|
+
9. **FedRAMP** -- `directLineCallerIdName`, `customName`, and `dialByName` are not available in Webex for Government. Use `firstName`/`lastName` instead. See [authentication.md → FedRAMP](authentication.md#webex-for-government-fedramp) for all FedRAMP restrictions.
|
|
1241
|
+
|
|
1242
|
+
### Auto Attendant API Gotchas
|
|
1243
|
+
|
|
1244
|
+
10. **`wxcli auto-attendants update` only supports basic fields** -- the CLI `update` command accepts `--name`, `--extension`, `--phone-number`, `--enabled` only. Menu configuration (`businessHoursMenu`, `afterHoursMenu`) requires raw HTTP PUT to `telephony/config/locations/{locationId}/autoAttendants/{aaId}`.
|
|
1245
|
+
|
|
1246
|
+
11. **`keyConfigurations.value` is mandatory in PUT** -- even for actions that don't use a destination (`TRANSFER_TO_OPERATOR`, `REPEAT_MENU`, `NAME_DIALING`, `EXTENSION_DIALING`), the `value` field must be present. Use `""` (empty string) for these actions. Omitting `value` or sending `null` causes error `25008 Missing Mandatory field name: HoursMenu.keyConfigurations.value`.
|
|
1247
|
+
|
|
1248
|
+
12. **`TRANSFER_TO_MAILBOX` requires a non-empty `value`** -- empty string `""` is rejected. Use the target AA's own extension (e.g., `"8000"`) to route to the AA's own voicemail. This is the extension of the auto attendant whose mailbox should receive the call.
|
|
1249
|
+
|
|
1250
|
+
13. **There is no `holidayMenu` field in the AA PUT body** -- the `holidayMenu` field is silently ignored by the API. The `afterHoursMenu` applies to both after-hours and holiday schedule periods. If you need different routing on holidays vs. after-hours, you need two separate auto attendants (one for after-hours, one for holidays).
|
|
1251
|
+
|
|
1252
|
+
14. **After-hours phone numbers are normalized on read-back** -- a number sent as `+19195559876` returns as `+1-9195559876` in GET responses. Do not use the GET value as input to a subsequent PUT; use the original format.
|
|
1253
|
+
|
|
1254
|
+
---
|
|
1255
|
+
|
|
1256
|
+
## Appendix: Feature Comparison
|
|
1257
|
+
|
|
1258
|
+
| Capability | Auto Attendant | Call Queue | Hunt Group |
|
|
1259
|
+
|------------|:--------------:|:----------:|:----------:|
|
|
1260
|
+
| IVR menu with key-press routing | Yes | No | No |
|
|
1261
|
+
| Hold calls in queue | No | Yes | No |
|
|
1262
|
+
| Ring agents by policy | No | Yes | Yes |
|
|
1263
|
+
| Business/after-hours menus | Yes | Via policies | Via `waiting_enabled` / `no_answer` |
|
|
1264
|
+
| Holiday service | Via schedule | Yes (policy API) | Via forwarding rules (schedule-based) |
|
|
1265
|
+
| Night service | Via schedule | Yes (policy API) | Via forwarding rules (schedule-based) |
|
|
1266
|
+
| Stranded calls handling | N/A | Yes (policy API) | N/A |
|
|
1267
|
+
| Forced forward | N/A | Yes (policy API) | N/A |
|
|
1268
|
+
| Agent join/unjoin | N/A | Yes | No |
|
|
1269
|
+
| Agent skill-based routing | N/A | Yes | No |
|
|
1270
|
+
| Agent weight-based routing | N/A | Yes | Yes |
|
|
1271
|
+
| Whisper message to agent | N/A | Yes | No |
|
|
1272
|
+
| Comfort/wait messages | N/A | Yes | No |
|
|
1273
|
+
| Music on hold | N/A | Yes | No |
|
|
1274
|
+
| Max agents (simultaneous) | N/A | 50 | 50 |
|
|
1275
|
+
| Max agents (WEIGHTED) | N/A | 100 | 100 |
|
|
1276
|
+
| Max agents (CIRCULAR/REGULAR/UNIFORM) | N/A | 1,000 | 1,000 |
|
|
1277
|
+
| Shared forwarding API | Yes | Yes | Yes |
|
|
1278
|
+
| Announcement file management | Yes | Yes | No |
|
|
1279
|
+
|
|
1280
|
+
---
|
|
1281
|
+
|
|
1282
|
+
## Gotchas (Cross-Cutting)
|
|
1283
|
+
|
|
1284
|
+
1. **Hunt groups ignore member personal call forwarding.** HG calls route directly to the agent's device and bypass any personal call forwarding the member has configured. Only the hunt group's own no-answer/forwarding settings govern overflow behavior.
|
|
1285
|
+
|
|
1286
|
+
2. **DND on a hunt group member skips them, not their voicemail.** If a member has DND enabled, the hunt group skips that member and moves to the next — it does NOT send the call to the member's personal voicemail. The HG's no-answer action only triggers after all members are exhausted.
|
|
1287
|
+
|
|
1288
|
+
3. **Partial updates are safer than full-object PUTs.** For all three features (AA, CQ, HG), sending the full GET response back as a PUT body can trigger validation errors on read-only or computed fields (e.g., `callingLineIdPolicy=CUSTOM` without a phone number on CQ). Always send only the fields you want to change.
|
|
1289
|
+
|
|
1290
|
+
2. **`--json-body` is required for nested settings.** The CLI generator skips deeply nested object/array body fields. Menu configurations (AA), queue settings with announcements (CQ), and call policies with no-answer/bounce config (HG) all require `--json-body '{ ... }'` instead of individual flags.
|
|
1291
|
+
|
|
1292
|
+
3. **Phone numbers normalize differently on read-back.** Numbers sent as `+19195559876` may return as `+1-9195559876` in GET responses. Do not round-trip GET values into PUT requests without stripping the dashes.
|
|
1293
|
+
|
|
1294
|
+
4. **Agents share the same model but differ in behavior.** The `Agent` object is used by both CQ and HG, but `joinEnabled` only applies to call queues, and `skillLevel` only applies to `SKILL_BASED` routing in CQ. Sending these fields to the wrong feature is silently ignored.
|
|
1295
|
+
|
|
1296
|
+
5. **Selective forwarding rule IDs change on name update.** Across all three features, renaming a selective forwarding rule changes its ID. The update response returns the new ID — capture it if you need to reference the rule again.
|
|
1297
|
+
|
|
1298
|
+
6. **Audio file upload IS supported via API.** Use the Announcement Repository API (`POST /telephony/config/announcements` or `POST /telephony/config/locations/{locationId}/announcements`) with multipart/form-data encoding. Supports WAV and WMA formats. See [location-calling-media.md](location-calling-media.md) section 1 for full upload details and examples.
|
|
1299
|
+
|
|
1300
|
+
---
|
|
1301
|
+
|
|
1302
|
+
## See Also
|
|
1303
|
+
|
|
1304
|
+
- [Provisioning Reference](provisioning.md) -- creating locations and users (prerequisites for all features in this doc)
|
|
1305
|
+
- [Additional Call Features](call-features-additional.md) -- Paging Groups, Call Park, Call Pickup, Voicemail Groups, and Customer Assist (Call Park recall uses Hunt Groups; Voicemail Groups can serve as overflow destinations for CQ/HG)
|
|
1306
|
+
- [Call Routing & PSTN](call-routing.md) -- dial plans, trunks, and route lists (AA/CQ/HG phone numbers participate in the call routing chain)
|
|
1307
|
+
- [Location Call Settings: Media](location-calling-media.md) -- schedule management (business hours and holiday schedules used by AA menus and CQ/HG policies)
|
|
1308
|
+
|
|
1309
|
+
## Migration Notes — CUCM Forwarding & Night Service
|
|
1310
|
+
|
|
1311
|
+
The CUCM-to-Webex migration pipeline writes hunt group and call queue forwarding via these per-feature endpoints:
|
|
1312
|
+
|
|
1313
|
+
- `PUT /telephony/config/locations/{locationId}/huntGroups/{huntGroupId}/callForwarding`
|
|
1314
|
+
- `PUT /telephony/config/locations/{locationId}/queues/{queueId}/callForwarding`
|
|
1315
|
+
- `PUT /telephony/config/locations/{locationId}/queues/{queueId}/holidayService`
|
|
1316
|
+
- `PUT /telephony/config/locations/{locationId}/queues/{queueId}/nightService`
|
|
1317
|
+
- `PUT /telephony/config/locations/{locationId}/queues/{queueId}/strandedCalls`
|
|
1318
|
+
- `PUT /telephony/config/locations/{locationId}/autoAttendants/{autoAttendantId}/callForwarding`
|
|
1319
|
+
|
|
1320
|
+
All endpoints require the same scope as feature creation (`spark-admin:telephony_config_write`). The migration tool only writes these settings when the corresponding CUCM source data is present; features without forwarding configuration are created with Webex defaults.
|