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,2037 @@
|
|
|
1
|
+
# Location Call Settings — Core Settings & Voicemail
|
|
2
|
+
|
|
3
|
+
## Sources
|
|
4
|
+
- wxc_sdk v1.30.0
|
|
5
|
+
- OpenAPI spec: specs/webex-cloud-calling.json
|
|
6
|
+
- developer.webex.com Location Call Settings APIs
|
|
7
|
+
|
|
8
|
+
Reference document covering the SDK APIs for location-level call settings, voicemail policies (location and org), voicemail rules, voice messaging, and voice portal configuration.
|
|
9
|
+
|
|
10
|
+
**SDK source module:** `wxc_sdk.telephony.location` (and related telephony modules)
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Table of Contents
|
|
15
|
+
|
|
16
|
+
1. [Location-Level Call Settings](#1-location-level-call-settings)
|
|
17
|
+
- [TelephonyLocationApi — Main API Class](#telephonylocationapi--main-api-class)
|
|
18
|
+
- [Data Models](#location-data-models)
|
|
19
|
+
- [Enable / List / Get / Update Locations](#enable--list--get--update-locations)
|
|
20
|
+
- [Caller ID](#caller-id)
|
|
21
|
+
- [Internal Dialing](#internal-dialing)
|
|
22
|
+
- [Call Intercept](#call-intercept)
|
|
23
|
+
- [Music on Hold](#music-on-hold)
|
|
24
|
+
- [Location Numbers](#location-numbers)
|
|
25
|
+
- [Emergency Callback Number (ECBN)](#emergency-callback-number-ecbn)
|
|
26
|
+
- [Announcement Language](#announcement-language)
|
|
27
|
+
- [Call Captions](#call-captions)
|
|
28
|
+
- [Device Settings](#device-settings)
|
|
29
|
+
- [Safe Delete Check](#safe-delete-check)
|
|
30
|
+
- [Extension Validation & Password Generation](#extension-validation--password-generation)
|
|
31
|
+
2. [Voicemail Policies](#2-voicemail-policies)
|
|
32
|
+
- [Location Voicemail Settings](#location-voicemail-settings)
|
|
33
|
+
- [Organisation Voicemail Settings](#organisation-voicemail-settings)
|
|
34
|
+
3. [Voicemail Rules (Org-Level Passcode Policy)](#3-voicemail-rules-org-level-passcode-policy)
|
|
35
|
+
4. [Voice Messaging (User-Level)](#4-voice-messaging-user-level)
|
|
36
|
+
5. [Voice Portal](#5-voice-portal)
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## 1. Location-Level Call Settings
|
|
41
|
+
|
|
42
|
+
### TelephonyLocationApi -- Main API Class
|
|
43
|
+
|
|
44
|
+
The main entry point is `TelephonyLocationApi`, accessible at `api.telephony.location`. It aggregates several child APIs as attributes:
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
base = 'telephony/config/locations'
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
| Attribute | Type | Purpose |
|
|
51
|
+
|-----------|------|---------|
|
|
52
|
+
| `emergency_services` | `LocationEmergencyServicesApi` | Emergency services config |
|
|
53
|
+
| `intercept` | `LocationInterceptApi` | Call intercept settings |
|
|
54
|
+
| `internal_dialing` | `InternalDialingApi` | Internal dialing / unknown extension routing |
|
|
55
|
+
| `moh` | `LocationMoHApi` | Music on hold settings |
|
|
56
|
+
| `number` | `LocationNumbersApi` | Phone number management (add/remove/activate) |
|
|
57
|
+
| `permissions_out` | `OutgoingPermissionsApi` | Outgoing call permissions |
|
|
58
|
+
| `voicemail` | `LocationVoicemailSettingsApi` | Location VM settings (transcription toggle) |
|
|
59
|
+
| `receptionist_contacts_directory` | `ReceptionistContactsDirectoryApi` | Receptionist contact directories |
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
### Location Data Models
|
|
64
|
+
|
|
65
|
+
#### `TelephonyLocation`
|
|
66
|
+
|
|
67
|
+
The core model representing a Webex Calling-enabled location.
|
|
68
|
+
|
|
69
|
+
| Field | Type | Description |
|
|
70
|
+
|-------|------|-------------|
|
|
71
|
+
| `location_id` | `str` | Unique identifier (aliased from `id`) |
|
|
72
|
+
| `name` | `str` | Location name |
|
|
73
|
+
| `announcement_language` | `str` | Phone announcement language |
|
|
74
|
+
| `calling_line_id` | `CallingLineId` | Caller ID name + phone number |
|
|
75
|
+
| `connection` | `PSTNConnection` | PSTN connection (TRUNK or ROUTE_GROUP) |
|
|
76
|
+
| `subscription_id` | `str` | PSTN subscription ID |
|
|
77
|
+
| `external_caller_id_name` | `str` | External caller ID name (Unicode) |
|
|
78
|
+
| `user_limit` | `int` | Max people at location (read-only) |
|
|
79
|
+
| `p_access_network_info` | `str` | Emergency SIP P-Access-Network-Info header |
|
|
80
|
+
| `outside_dial_digit` | `str` | Digit to dial for outside line (e.g. `'9'`) |
|
|
81
|
+
| `enforce_outside_dial_digit` | `bool` | Enforce outside dial digit for PSTN calls |
|
|
82
|
+
| `routing_prefix` | `str` | Prefix for inter-location calls with same extension |
|
|
83
|
+
| `default_domain` | `str` | IP/hostname/domain (read-only) |
|
|
84
|
+
| `charge_number` | `str` | P-Charge-Info header number for PSTN calls |
|
|
85
|
+
| `use_charge_number_for_pcharge_info` | `bool` | Enable charge number in SIP INVITE |
|
|
86
|
+
| `e911_setup_required` | `bool` | Whether E911 setup is needed (read-only) |
|
|
87
|
+
|
|
88
|
+
**Read-only fields** (excluded from updates): `location_id`, `name`, `subscription_id`, `user_limit`, `default_domain`, `e911_setup_required`.
|
|
89
|
+
|
|
90
|
+
#### `CallingLineId`
|
|
91
|
+
|
|
92
|
+
| Field | Type | Description |
|
|
93
|
+
|-------|------|-------------|
|
|
94
|
+
| `name` | `str` | Group calling line ID name (defaults to org name). When updating, include phone_number too. |
|
|
95
|
+
| `phone_number` | `str` | Main number in E.164 format |
|
|
96
|
+
|
|
97
|
+
#### `PSTNConnection`
|
|
98
|
+
|
|
99
|
+
| Field | Type | Description |
|
|
100
|
+
|-------|------|-------------|
|
|
101
|
+
| `type` | `RouteType` | `TRUNK` or `ROUTE_GROUP` |
|
|
102
|
+
| `id` | `str` | Unique identifier of the route |
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
### Enable / List / Get / Update Locations
|
|
107
|
+
|
|
108
|
+
#### `enable_for_calling`
|
|
109
|
+
|
|
110
|
+
Enable a location for Webex Calling. Adds calling support to a location created via the locations API.
|
|
111
|
+
|
|
112
|
+
```python
|
|
113
|
+
def enable_for_calling(
|
|
114
|
+
self,
|
|
115
|
+
location: Location,
|
|
116
|
+
org_id: str = None
|
|
117
|
+
) -> str
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
**Returns:** The new location ID.
|
|
121
|
+
|
|
122
|
+
**Scope:** `spark-admin:telephony_config_write`
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
#### `list`
|
|
127
|
+
|
|
128
|
+
List all Webex Calling locations with telephony details.
|
|
129
|
+
|
|
130
|
+
```python
|
|
131
|
+
def list(
|
|
132
|
+
self,
|
|
133
|
+
name: str = None,
|
|
134
|
+
order: str = None,
|
|
135
|
+
org_id: str = None
|
|
136
|
+
) -> Generator[TelephonyLocation, None, None]
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
| Parameter | Description |
|
|
140
|
+
|-----------|-------------|
|
|
141
|
+
| `name` | Filter — locations whose name contains this string |
|
|
142
|
+
| `order` | Sort by name: `'asc'` or `'desc'` |
|
|
143
|
+
|
|
144
|
+
**Scope:** `spark-admin:telephony_config_read`
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
#### `details`
|
|
149
|
+
|
|
150
|
+
Get Webex Calling details for a single location.
|
|
151
|
+
|
|
152
|
+
```python
|
|
153
|
+
def details(
|
|
154
|
+
self,
|
|
155
|
+
location_id: str,
|
|
156
|
+
org_id: str = None
|
|
157
|
+
) -> TelephonyLocation
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
**Scope:** `spark-admin:telephony_config_read`
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
#### `update`
|
|
165
|
+
|
|
166
|
+
Update Webex Calling details for a location. Only non-read-only fields in `TelephonyLocation` are sent.
|
|
167
|
+
|
|
168
|
+
```python
|
|
169
|
+
def update(
|
|
170
|
+
self,
|
|
171
|
+
location_id: str,
|
|
172
|
+
settings: TelephonyLocation,
|
|
173
|
+
org_id: str = None
|
|
174
|
+
) -> Optional[str]
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
**Returns:** `batchJobId` if an async update job is created, otherwise `None`.
|
|
178
|
+
|
|
179
|
+
**Example:**
|
|
180
|
+
```python
|
|
181
|
+
api.telephony.location.update(
|
|
182
|
+
location_id=location_id,
|
|
183
|
+
settings=TelephonyLocation(
|
|
184
|
+
calling_line_id=CallingLineId(phone_number=tn),
|
|
185
|
+
routing_prefix=routing_prefix,
|
|
186
|
+
outside_dial_digit='9'
|
|
187
|
+
)
|
|
188
|
+
)
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
**Scope:** `spark-admin:telephony_config_write`
|
|
192
|
+
|
|
193
|
+
**Note:** Modifying `connection` is only supported for local PSTN types `TRUNK` and `ROUTE_GROUP`.
|
|
194
|
+
|
|
195
|
+
#### CLI Examples
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
# List all locations with Webex Calling details
|
|
199
|
+
wxcli location-settings list-1
|
|
200
|
+
|
|
201
|
+
# List locations filtered by name
|
|
202
|
+
wxcli location-settings list-1 --name "San Jose"
|
|
203
|
+
|
|
204
|
+
# Get calling details for a specific location
|
|
205
|
+
wxcli location-settings show Y2lzY29zcGFyazovL...
|
|
206
|
+
|
|
207
|
+
# Enable a location for Webex Calling
|
|
208
|
+
wxcli location-settings create \
|
|
209
|
+
--id Y2lzY29zcGFyazovL... \
|
|
210
|
+
--name "San Jose HQ" \
|
|
211
|
+
--time-zone "America/Los_Angeles" \
|
|
212
|
+
--preferred-language "en_us" \
|
|
213
|
+
--announcement-language "en_us"
|
|
214
|
+
|
|
215
|
+
# Update location calling details (outside dial digit, routing prefix)
|
|
216
|
+
wxcli location-settings update Y2lzY29zcGFyazovL... \
|
|
217
|
+
--outside-dial-digit "9" \
|
|
218
|
+
--enforce-outside-dial-digit \
|
|
219
|
+
--routing-prefix "8001" \
|
|
220
|
+
--external-caller-id-name "Acme Corp"
|
|
221
|
+
|
|
222
|
+
# Update location with JSON body for complex settings
|
|
223
|
+
wxcli location-settings update Y2lzY29zcGFyazovL... \
|
|
224
|
+
--json-body '{"announcementLanguage": "en_us", "chargeNumber": "+14085551234"}'
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
### Caller ID
|
|
230
|
+
|
|
231
|
+
Caller ID is configured through the `CallingLineId` object embedded in `TelephonyLocation`. There is also a dedicated API to list phone numbers available for external caller ID.
|
|
232
|
+
|
|
233
|
+
#### `phone_numbers_available_for_external_caller_id`
|
|
234
|
+
|
|
235
|
+
List phone numbers available for external caller ID usage by a Webex Calling entity within a location.
|
|
236
|
+
|
|
237
|
+
```python
|
|
238
|
+
def phone_numbers_available_for_external_caller_id(
|
|
239
|
+
self,
|
|
240
|
+
location_id: str,
|
|
241
|
+
phone_number: List[str] = None,
|
|
242
|
+
owner_name: str = None,
|
|
243
|
+
person_id: str = None,
|
|
244
|
+
org_id: str = None,
|
|
245
|
+
**params
|
|
246
|
+
) -> Generator[AvailableNumber, None, None]
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
Numbers from the specified location and cross-location numbers (same country, PSTN provider, zone) are returned. When `person_id` is specified for a Cisco PSTN location user with a mobile primary DN and no billing plan, only that mobile number is returned.
|
|
250
|
+
|
|
251
|
+
**Scope:** `spark-admin:telephony_config_read`
|
|
252
|
+
|
|
253
|
+
---
|
|
254
|
+
|
|
255
|
+
### Internal Dialing
|
|
256
|
+
|
|
257
|
+
**API path:** `api.telephony.location.internal_dialing`
|
|
258
|
+
|
|
259
|
+
Controls routing of calls to unknown extensions (2-6 digits) to a premises PBX via a trunk or route group.
|
|
260
|
+
|
|
261
|
+
#### `InternalDialing` Model
|
|
262
|
+
|
|
263
|
+
| Field | Type | Description |
|
|
264
|
+
|-------|------|-------------|
|
|
265
|
+
| `enable_unknown_extension_route_policy` | `bool` | Route unknown extensions to premises |
|
|
266
|
+
| `unknown_extension_route_identity` | `RouteIdentity` | Destination trunk/route group for unknown extensions |
|
|
267
|
+
|
|
268
|
+
#### `read`
|
|
269
|
+
|
|
270
|
+
```python
|
|
271
|
+
def read(
|
|
272
|
+
self,
|
|
273
|
+
location_id: str,
|
|
274
|
+
org_id: str = None
|
|
275
|
+
) -> InternalDialing
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
**Scope:** `spark-admin:telephony_config_read`
|
|
279
|
+
|
|
280
|
+
#### `update`
|
|
281
|
+
|
|
282
|
+
```python
|
|
283
|
+
def update(
|
|
284
|
+
self,
|
|
285
|
+
location_id: str,
|
|
286
|
+
update: InternalDialing,
|
|
287
|
+
org_id: str = None
|
|
288
|
+
)
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
**Scope:** `spark-admin:telephony_config_write`
|
|
292
|
+
|
|
293
|
+
#### CLI Examples
|
|
294
|
+
|
|
295
|
+
```bash
|
|
296
|
+
# Read internal dialing configuration for a location
|
|
297
|
+
wxcli location-call-handling show Y2lzY29zcGFyazovL...
|
|
298
|
+
|
|
299
|
+
# Enable routing of unknown extensions to a trunk
|
|
300
|
+
wxcli location-call-handling update Y2lzY29zcGFyazovL... \
|
|
301
|
+
--enable-unknown-extension-route-policy \
|
|
302
|
+
--json-body '{"unknownExtensionRouteIdentity": {"id": "TRUNK_ID", "type": "TRUNK"}}'
|
|
303
|
+
|
|
304
|
+
# Disable unknown extension routing
|
|
305
|
+
wxcli location-call-handling update Y2lzY29zcGFyazovL... \
|
|
306
|
+
--no-enable-unknown-extension-route-policy
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
---
|
|
310
|
+
|
|
311
|
+
### Call Intercept
|
|
312
|
+
|
|
313
|
+
**API path:** `api.telephony.location.intercept`
|
|
314
|
+
|
|
315
|
+
Intercept incoming or outgoing calls for all persons at a location. Intercepted calls are routed to a designated number or to voicemail.
|
|
316
|
+
|
|
317
|
+
Uses the shared `InterceptSetting` model from `wxc_sdk.person_settings.call_intercept`.
|
|
318
|
+
|
|
319
|
+
#### `read`
|
|
320
|
+
|
|
321
|
+
```python
|
|
322
|
+
def read(
|
|
323
|
+
self,
|
|
324
|
+
location_id: str,
|
|
325
|
+
org_id: str = None
|
|
326
|
+
) -> InterceptSetting
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
**Scope:** `spark-admin:telephony_config_read`
|
|
330
|
+
|
|
331
|
+
#### `configure`
|
|
332
|
+
|
|
333
|
+
```python
|
|
334
|
+
def configure(
|
|
335
|
+
self,
|
|
336
|
+
location_id: str,
|
|
337
|
+
settings: InterceptSetting,
|
|
338
|
+
org_id: str = None
|
|
339
|
+
)
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
**Scope:** `spark-admin:telephony_config_write`
|
|
343
|
+
|
|
344
|
+
#### `call_intercept_available_phone_numbers`
|
|
345
|
+
|
|
346
|
+
(On `TelephonyLocationApi` directly.) List service and standard numbers available to be assigned as the location's call intercept number.
|
|
347
|
+
|
|
348
|
+
```python
|
|
349
|
+
def call_intercept_available_phone_numbers(
|
|
350
|
+
self,
|
|
351
|
+
location_id: str,
|
|
352
|
+
phone_number: List[str] = None,
|
|
353
|
+
owner_name: str = None,
|
|
354
|
+
org_id: str = None,
|
|
355
|
+
**params
|
|
356
|
+
) -> Generator[AvailableNumber, None, None]
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
**Scope:** `spark-admin:telephony_config_read`
|
|
360
|
+
|
|
361
|
+
#### CLI Examples
|
|
362
|
+
|
|
363
|
+
```bash
|
|
364
|
+
# Read call intercept settings for a location
|
|
365
|
+
wxcli location-call-handling show-intercept Y2lzY29zcGFyazovL...
|
|
366
|
+
|
|
367
|
+
# Enable call intercept for all users at a location
|
|
368
|
+
wxcli location-call-handling update-intercept Y2lzY29zcGFyazovL... --enabled
|
|
369
|
+
|
|
370
|
+
# Enable intercept with voicemail routing via JSON body
|
|
371
|
+
wxcli location-call-handling update-intercept Y2lzY29zcGFyazovL... \
|
|
372
|
+
--json-body '{"enabled": true, "incoming": {"type": "INTERCEPT_ALL", "voicemailEnabled": true}}'
|
|
373
|
+
|
|
374
|
+
# Disable call intercept
|
|
375
|
+
wxcli location-call-handling update-intercept Y2lzY29zcGFyazovL... --no-enabled
|
|
376
|
+
|
|
377
|
+
# List available phone numbers for call intercept
|
|
378
|
+
wxcli location-settings list-available-numbers-call-intercept Y2lzY29zcGFyazovL...
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
---
|
|
382
|
+
|
|
383
|
+
### Music on Hold
|
|
384
|
+
|
|
385
|
+
**API path:** `api.telephony.location.moh`
|
|
386
|
+
|
|
387
|
+
Controls music played when a call is on hold or parked at the location.
|
|
388
|
+
|
|
389
|
+
#### `LocationMoHGreetingType` Enum
|
|
390
|
+
|
|
391
|
+
| Value | Description |
|
|
392
|
+
|-------|-------------|
|
|
393
|
+
| `SYSTEM` | Default system music |
|
|
394
|
+
| `CUSTOM` | Custom uploaded audio file or playlist |
|
|
395
|
+
|
|
396
|
+
#### `LocationMoHSetting` Model
|
|
397
|
+
|
|
398
|
+
| Field | Type | Description |
|
|
399
|
+
|-------|------|-------------|
|
|
400
|
+
| `call_hold_enabled` | `bool` | Play music on hold |
|
|
401
|
+
| `call_park_enabled` | `bool` | Play music on park |
|
|
402
|
+
| `greeting` | `LocationMoHGreetingType` | `SYSTEM` or `CUSTOM` |
|
|
403
|
+
| `audio_file` | `AnnAudioFile` | Audio file details (when `CUSTOM`) |
|
|
404
|
+
| `playlist` | `IdAndName` | Playlist details (when `CUSTOM`) |
|
|
405
|
+
|
|
406
|
+
#### `read`
|
|
407
|
+
|
|
408
|
+
```python
|
|
409
|
+
def read(
|
|
410
|
+
self,
|
|
411
|
+
location_id: str,
|
|
412
|
+
org_id: str = None
|
|
413
|
+
) -> LocationMoHSetting
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
**Scope:** `spark-admin:telephony_config_read`
|
|
417
|
+
|
|
418
|
+
#### `update`
|
|
419
|
+
|
|
420
|
+
```python
|
|
421
|
+
def update(
|
|
422
|
+
self,
|
|
423
|
+
location_id: str,
|
|
424
|
+
settings: LocationMoHSetting,
|
|
425
|
+
org_id: str = None
|
|
426
|
+
)
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
**Scope:** `spark-admin:telephony_config_write`
|
|
430
|
+
|
|
431
|
+
#### CLI Examples
|
|
432
|
+
|
|
433
|
+
```bash
|
|
434
|
+
# Read music on hold settings for a location
|
|
435
|
+
wxcli location-settings show-music-on-hold Y2lzY29zcGFyazovL...
|
|
436
|
+
|
|
437
|
+
# Enable music on hold with system greeting
|
|
438
|
+
wxcli location-settings update-music-on-hold Y2lzY29zcGFyazovL... \
|
|
439
|
+
--moh-enabled --greeting DEFAULT
|
|
440
|
+
|
|
441
|
+
# Switch to custom greeting
|
|
442
|
+
wxcli location-settings update-music-on-hold Y2lzY29zcGFyazovL... \
|
|
443
|
+
--moh-enabled --greeting CUSTOM
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
---
|
|
447
|
+
|
|
448
|
+
### Location Numbers
|
|
449
|
+
|
|
450
|
+
**API path:** `api.telephony.location.number`
|
|
451
|
+
|
|
452
|
+
Manage phone numbers assigned to a location (add, remove, activate, deactivate).
|
|
453
|
+
|
|
454
|
+
#### Key Models
|
|
455
|
+
|
|
456
|
+
| Model | Description |
|
|
457
|
+
|-------|-------------|
|
|
458
|
+
| `TelephoneNumberType` | Enum: `TOLLFREE`, `DID`, `MOBILE` |
|
|
459
|
+
| `NumberUsageType` | Enum: `NONE` (standard), `SERVICE` (high-volume, e.g. Contact Center) |
|
|
460
|
+
| `NumbersRequestAction` | Enum: `ACTIVATE`, `DEACTIVATE` |
|
|
461
|
+
|
|
462
|
+
#### `add`
|
|
463
|
+
|
|
464
|
+
```python
|
|
465
|
+
def add(
|
|
466
|
+
self,
|
|
467
|
+
location_id: str,
|
|
468
|
+
phone_numbers: list[str],
|
|
469
|
+
number_type: TelephoneNumberType = None,
|
|
470
|
+
number_usage_type: NumberUsageType = None,
|
|
471
|
+
state: NumberState = NumberState.inactive,
|
|
472
|
+
subscription_id: str = None,
|
|
473
|
+
carrier_id: str = None,
|
|
474
|
+
org_id: str = None
|
|
475
|
+
) -> NumberAddResponse
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
Only supported for non-integrated PSTN (LGW, Non-integrated CPP). Max 20 mobile numbers per request. Numbers already at the location are silently ignored.
|
|
479
|
+
|
|
480
|
+
#### `remove`
|
|
481
|
+
|
|
482
|
+
```python
|
|
483
|
+
def remove(
|
|
484
|
+
self,
|
|
485
|
+
location_id: str,
|
|
486
|
+
phone_numbers: list[str],
|
|
487
|
+
org_id: str = None
|
|
488
|
+
)
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
A location's main number cannot be removed. Only non-integrated PSTN.
|
|
492
|
+
|
|
493
|
+
#### `activate`
|
|
494
|
+
|
|
495
|
+
```python
|
|
496
|
+
def activate(
|
|
497
|
+
self,
|
|
498
|
+
location_id: str,
|
|
499
|
+
phone_numbers: list[str],
|
|
500
|
+
org_id: str = None
|
|
501
|
+
)
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
Does not activate mobile numbers (those activate on user assignment).
|
|
505
|
+
|
|
506
|
+
#### `manage_number_state`
|
|
507
|
+
|
|
508
|
+
```python
|
|
509
|
+
def manage_number_state(
|
|
510
|
+
self,
|
|
511
|
+
location_id: str,
|
|
512
|
+
phone_numbers: list[str],
|
|
513
|
+
action: NumbersRequestAction = None,
|
|
514
|
+
org_id: str = None
|
|
515
|
+
)
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
Unified activate/deactivate. Deactivate limitations: max 500 numbers, must be unassigned, not ECBN, not mobile, non-integrated PSTN only.
|
|
519
|
+
|
|
520
|
+
---
|
|
521
|
+
|
|
522
|
+
### Emergency Callback Number (ECBN)
|
|
523
|
+
|
|
524
|
+
#### `read_ecbn`
|
|
525
|
+
|
|
526
|
+
```python
|
|
527
|
+
def read_ecbn(
|
|
528
|
+
self,
|
|
529
|
+
location_id: str,
|
|
530
|
+
org_id: str = None
|
|
531
|
+
) -> LocationECBN
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
**Scope:** `spark-admin:telephony_config_read`
|
|
535
|
+
|
|
536
|
+
#### `update_ecbn`
|
|
537
|
+
|
|
538
|
+
```python
|
|
539
|
+
def update_ecbn(
|
|
540
|
+
self,
|
|
541
|
+
location_id: str,
|
|
542
|
+
selected: CallBackSelected,
|
|
543
|
+
location_member_id: str = None,
|
|
544
|
+
org_id: str = None
|
|
545
|
+
)
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
| `CallBackSelected` Value | Description |
|
|
549
|
+
|--------------------------|-------------|
|
|
550
|
+
| `LOCATION_NUMBER` | Use the location's TN |
|
|
551
|
+
| `LOCATION_MEMBER_NUMBER` | Use a member's number (requires `location_member_id`) |
|
|
552
|
+
|
|
553
|
+
**Scope:** `spark-admin:telephony_config_write`
|
|
554
|
+
|
|
555
|
+
#### `ecbn_available_phone_numbers`
|
|
556
|
+
|
|
557
|
+
```python
|
|
558
|
+
def ecbn_available_phone_numbers(
|
|
559
|
+
self,
|
|
560
|
+
location_id: str,
|
|
561
|
+
phone_number: List[str] = None,
|
|
562
|
+
owner_name: str = None,
|
|
563
|
+
org_id: str = None,
|
|
564
|
+
**params
|
|
565
|
+
) -> Generator[AvailableNumber, None, None]
|
|
566
|
+
```
|
|
567
|
+
|
|
568
|
+
#### `LocationECBN` Model
|
|
569
|
+
|
|
570
|
+
| Field | Type | Description |
|
|
571
|
+
|-------|------|-------------|
|
|
572
|
+
| `location_info` | `LocationECBNLocation` | Location-level ECBN data (phone_number, name, effective_level, effective_value, quality) |
|
|
573
|
+
| `location_member_info` | `LocationECBNLocationMember` | Member-level ECBN data (phone_number, first/last name, member_id, member_type, effective_level, effective_value, quality) |
|
|
574
|
+
| `selected` | `CallBackSelected` | Which number type is selected |
|
|
575
|
+
|
|
576
|
+
#### CLI Examples
|
|
577
|
+
|
|
578
|
+
```bash
|
|
579
|
+
# Read ECBN settings for a location
|
|
580
|
+
wxcli location-settings show-emergency-callback-number Y2lzY29zcGFyazovL...
|
|
581
|
+
|
|
582
|
+
# Update ECBN to use the location's main number
|
|
583
|
+
wxcli location-settings update-emergency-callback-number Y2lzY29zcGFyazovL... \
|
|
584
|
+
--json-body '{"selected": "LOCATION_NUMBER"}'
|
|
585
|
+
|
|
586
|
+
# Update ECBN to use a specific member's number
|
|
587
|
+
wxcli location-settings update-emergency-callback-number Y2lzY29zcGFyazovL... \
|
|
588
|
+
--location-member-id MEMBER_ID \
|
|
589
|
+
--json-body '{"selected": "LOCATION_MEMBER_NUMBER", "locationMemberId": "MEMBER_ID"}'
|
|
590
|
+
|
|
591
|
+
# List available ECBN phone numbers
|
|
592
|
+
wxcli location-settings list-available-numbers-emergency-callback-number Y2lzY29zcGFyazovL...
|
|
593
|
+
```
|
|
594
|
+
|
|
595
|
+
---
|
|
596
|
+
|
|
597
|
+
### Announcement Language
|
|
598
|
+
|
|
599
|
+
#### `change_announcement_language`
|
|
600
|
+
|
|
601
|
+
Change the announcement language for existing people/workspaces and/or feature configurations at a location. Does **not** change the default language for new entities.
|
|
602
|
+
|
|
603
|
+
```python
|
|
604
|
+
def change_announcement_language(
|
|
605
|
+
self,
|
|
606
|
+
location_id: str,
|
|
607
|
+
language_code: str,
|
|
608
|
+
agent_enabled: bool = None,
|
|
609
|
+
service_enabled: bool = None,
|
|
610
|
+
org_id: str = None
|
|
611
|
+
)
|
|
612
|
+
```
|
|
613
|
+
|
|
614
|
+
| Parameter | Description |
|
|
615
|
+
|-----------|-------------|
|
|
616
|
+
| `language_code` | Language code to set |
|
|
617
|
+
| `agent_enabled` | `True` to change language for existing people/workspaces |
|
|
618
|
+
| `service_enabled` | `True` to change language for existing feature configurations |
|
|
619
|
+
|
|
620
|
+
**Scope:** `spark-admin:telephony_config_write`
|
|
621
|
+
|
|
622
|
+
#### CLI Examples
|
|
623
|
+
|
|
624
|
+
```bash
|
|
625
|
+
# Change announcement language for existing people and features at a location
|
|
626
|
+
wxcli location-settings change-announcement-language Y2lzY29zcGFyazovL... \
|
|
627
|
+
--announcement-language-code "en_us" \
|
|
628
|
+
--agent-enabled true \
|
|
629
|
+
--service-enabled true
|
|
630
|
+
```
|
|
631
|
+
|
|
632
|
+
---
|
|
633
|
+
|
|
634
|
+
### Call Captions
|
|
635
|
+
|
|
636
|
+
#### `LocationCallCaptions` Model
|
|
637
|
+
|
|
638
|
+
| Field | Type | Description |
|
|
639
|
+
|-------|------|-------------|
|
|
640
|
+
| `location_closed_captions_enabled` | `bool` | Location-level closed captions on/off |
|
|
641
|
+
| `location_transcripts_enabled` | `bool` | Location-level transcripts on/off |
|
|
642
|
+
| `org_closed_captions_enabled` | `bool` | Org-level closed captions (read-only) |
|
|
643
|
+
| `org_transcripts_enabled` | `bool` | Org-level transcripts (read-only) |
|
|
644
|
+
| `use_org_settings_enabled` | `bool` | `True` = org settings override location settings |
|
|
645
|
+
|
|
646
|
+
**Note:** Not supported for locations in India.
|
|
647
|
+
|
|
648
|
+
#### `get_call_captions_settings`
|
|
649
|
+
|
|
650
|
+
```python
|
|
651
|
+
def get_call_captions_settings(
|
|
652
|
+
self,
|
|
653
|
+
location_id: str,
|
|
654
|
+
org_id: str = None
|
|
655
|
+
) -> LocationCallCaptions
|
|
656
|
+
```
|
|
657
|
+
|
|
658
|
+
#### `update_call_captions_settings`
|
|
659
|
+
|
|
660
|
+
```python
|
|
661
|
+
def update_call_captions_settings(
|
|
662
|
+
self,
|
|
663
|
+
location_id: str,
|
|
664
|
+
settings: LocationCallCaptions,
|
|
665
|
+
org_id: str = None
|
|
666
|
+
)
|
|
667
|
+
```
|
|
668
|
+
|
|
669
|
+
Only location-level fields and `use_org_settings_enabled` are sent on update; org-level fields are excluded.
|
|
670
|
+
|
|
671
|
+
#### CLI Examples
|
|
672
|
+
|
|
673
|
+
```bash
|
|
674
|
+
# Read call captions settings for a location
|
|
675
|
+
wxcli location-settings show-call-captions Y2lzY29zcGFyazovL...
|
|
676
|
+
|
|
677
|
+
# Enable location-level closed captions and transcripts
|
|
678
|
+
wxcli location-settings update-call-captions Y2lzY29zcGFyazovL... \
|
|
679
|
+
--location-closed-captions-enabled \
|
|
680
|
+
--location-transcripts-enabled \
|
|
681
|
+
--no-use-org-settings-enabled
|
|
682
|
+
|
|
683
|
+
# Use org-level settings instead of location overrides
|
|
684
|
+
wxcli location-settings update-call-captions Y2lzY29zcGFyazovL... \
|
|
685
|
+
--use-org-settings-enabled
|
|
686
|
+
```
|
|
687
|
+
|
|
688
|
+
---
|
|
689
|
+
|
|
690
|
+
### Device Settings
|
|
691
|
+
|
|
692
|
+
#### `device_settings`
|
|
693
|
+
|
|
694
|
+
Get device override settings for a location.
|
|
695
|
+
|
|
696
|
+
```python
|
|
697
|
+
def device_settings(
|
|
698
|
+
self,
|
|
699
|
+
location_id: str,
|
|
700
|
+
org_id: str = None
|
|
701
|
+
) -> DeviceCustomization
|
|
702
|
+
```
|
|
703
|
+
|
|
704
|
+
**Scope:** `spark-admin:telephony_config_read`
|
|
705
|
+
|
|
706
|
+
---
|
|
707
|
+
|
|
708
|
+
### Safe Delete Check
|
|
709
|
+
|
|
710
|
+
#### `safe_delete_check_before_disabling_calling_location`
|
|
711
|
+
|
|
712
|
+
Check whether a calling location can be safely disabled. Returns blockers and warnings.
|
|
713
|
+
|
|
714
|
+
```python
|
|
715
|
+
def safe_delete_check_before_disabling_calling_location(
|
|
716
|
+
self,
|
|
717
|
+
location_id: str,
|
|
718
|
+
org_id: str = None
|
|
719
|
+
) -> SafeDeleteCheckResponse
|
|
720
|
+
```
|
|
721
|
+
|
|
722
|
+
#### `SafeDeleteCheckResponse` Model
|
|
723
|
+
|
|
724
|
+
| Field | Type | Description |
|
|
725
|
+
|-------|------|-------------|
|
|
726
|
+
| `location_delete_status` | `LocationDeleteStatus` | `BLOCKED`, `UNBLOCKED`, or `FORCE_REQUIRED` |
|
|
727
|
+
| `blocking` | `BlockingDisableCalling` | Hard blockers: last_location, trunks_in_use_count, users_in_use_count, workspaces_in_use_count, virtual_line_in_use_count, numbers_order_pending |
|
|
728
|
+
| `non_blocking` | `NonBlockingDisableCalling` | Warnings: numbers_present |
|
|
729
|
+
| `blocking_unless_forced` | `BlockingUnlessForced` | Soft blockers: non_user_entities_in_use, trunks_count |
|
|
730
|
+
|
|
731
|
+
**Scope:** `spark-admin:telephony_config_read`
|
|
732
|
+
|
|
733
|
+
#### CLI Examples
|
|
734
|
+
|
|
735
|
+
```bash
|
|
736
|
+
# Check if a location can be safely disabled for calling
|
|
737
|
+
wxcli location-settings safe-delete-check Y2lzY29zcGFyazovL...
|
|
738
|
+
```
|
|
739
|
+
|
|
740
|
+
---
|
|
741
|
+
|
|
742
|
+
### Extension Validation & Password Generation
|
|
743
|
+
|
|
744
|
+
#### `validate_extensions`
|
|
745
|
+
|
|
746
|
+
```python
|
|
747
|
+
def validate_extensions(
|
|
748
|
+
self,
|
|
749
|
+
location_id: str,
|
|
750
|
+
extensions: list[str],
|
|
751
|
+
org_id: str = None
|
|
752
|
+
) -> ValidateExtensionsResponse
|
|
753
|
+
```
|
|
754
|
+
|
|
755
|
+
**Scope:** `spark-admin:telephony_config_write`
|
|
756
|
+
|
|
757
|
+
#### `generate_password`
|
|
758
|
+
|
|
759
|
+
Generate an example SIP password using the location's effective password settings. Used during trunk creation.
|
|
760
|
+
|
|
761
|
+
```python
|
|
762
|
+
def generate_password(
|
|
763
|
+
self,
|
|
764
|
+
location_id: str,
|
|
765
|
+
generate: list[str] = None,
|
|
766
|
+
org_id: str = None
|
|
767
|
+
) -> str
|
|
768
|
+
```
|
|
769
|
+
|
|
770
|
+
**Returns:** The generated example SIP password string.
|
|
771
|
+
|
|
772
|
+
**Scope:** `spark-admin:telephony_config_write`
|
|
773
|
+
|
|
774
|
+
#### CLI Examples
|
|
775
|
+
|
|
776
|
+
```bash
|
|
777
|
+
# Validate extensions at a location
|
|
778
|
+
wxcli location-settings validate-extensions Y2lzY29zcGFyazovL... \
|
|
779
|
+
--json-body '{"extensions": ["1000", "1001", "1002"]}'
|
|
780
|
+
|
|
781
|
+
# Generate an example SIP password for a location
|
|
782
|
+
wxcli location-call-handling generate-example-password Y2lzY29zcGFyazovL...
|
|
783
|
+
```
|
|
784
|
+
|
|
785
|
+
---
|
|
786
|
+
|
|
787
|
+
### Raw HTTP
|
|
788
|
+
<!-- Updated by playbook session 2026-03-18 -->
|
|
789
|
+
|
|
790
|
+
```python
|
|
791
|
+
from wxc_sdk import WebexSimpleApi
|
|
792
|
+
api = WebexSimpleApi() # auth via WEBEX_ACCESS_TOKEN env var
|
|
793
|
+
BASE = "https://webexapis.com/v1"
|
|
794
|
+
```
|
|
795
|
+
|
|
796
|
+
All location-level call settings use raw HTTP via `api.session.rest_*()` methods. Full URLs are required. No auto-pagination -- pass `max=1000` for list endpoints. Responses are JSON dicts. Errors raise `RestError`.
|
|
797
|
+
|
|
798
|
+
#### Location Calling Config (List / Get / Enable / Update)
|
|
799
|
+
|
|
800
|
+
**List locations with calling details:**
|
|
801
|
+
```python
|
|
802
|
+
params = {"max": 1000}
|
|
803
|
+
result = api.session.rest_get(f"{BASE}/telephony/config/locations", params=params)
|
|
804
|
+
locations = result.get("locations", [])
|
|
805
|
+
# Each item: {"id", "name", "announcementLanguage", "callingLineId", "connection", ...}
|
|
806
|
+
```
|
|
807
|
+
|
|
808
|
+
**Get a single location's calling details:**
|
|
809
|
+
```python
|
|
810
|
+
loc = api.session.rest_get(f"{BASE}/telephony/config/locations/{loc_id}")
|
|
811
|
+
```
|
|
812
|
+
|
|
813
|
+
**Enable a location for calling:**
|
|
814
|
+
```python
|
|
815
|
+
body = {
|
|
816
|
+
"id": location_id, # existing location ID from Locations API
|
|
817
|
+
"name": "San Jose HQ",
|
|
818
|
+
"timeZone": "America/Los_Angeles",
|
|
819
|
+
"preferredLanguage": "en_us",
|
|
820
|
+
"announcementLanguage": "en_us"
|
|
821
|
+
}
|
|
822
|
+
result = api.session.rest_post(f"{BASE}/telephony/config/locations", json=body)
|
|
823
|
+
```
|
|
824
|
+
|
|
825
|
+
**Update location calling details:**
|
|
826
|
+
```python
|
|
827
|
+
body = {
|
|
828
|
+
"announcementLanguage": "en_us",
|
|
829
|
+
"outsideDialDigit": "9",
|
|
830
|
+
"enforceOutsideDialDigit": True,
|
|
831
|
+
"routingPrefix": "8001",
|
|
832
|
+
"externalCallerIdName": "Acme Corp"
|
|
833
|
+
}
|
|
834
|
+
api.session.rest_put(f"{BASE}/telephony/config/locations/{loc_id}", json=body)
|
|
835
|
+
# Returns batchJobId if async update, otherwise None
|
|
836
|
+
```
|
|
837
|
+
|
|
838
|
+
#### Internal Dialing
|
|
839
|
+
|
|
840
|
+
**Read internal dialing settings:**
|
|
841
|
+
```python
|
|
842
|
+
result = api.session.rest_get(f"{BASE}/telephony/config/locations/{loc_id}/internalDialing")
|
|
843
|
+
# {"enableUnknownExtensionRoutePolicy": bool, "unknownExtensionRouteIdentity": {...}}
|
|
844
|
+
```
|
|
845
|
+
|
|
846
|
+
**Update internal dialing:**
|
|
847
|
+
```python
|
|
848
|
+
body = {
|
|
849
|
+
"enableUnknownExtensionRoutePolicy": True,
|
|
850
|
+
"unknownExtensionRouteIdentity": {"id": trunk_id, "type": "TRUNK"}
|
|
851
|
+
}
|
|
852
|
+
api.session.rest_put(f"{BASE}/telephony/config/locations/{loc_id}/internalDialing", json=body)
|
|
853
|
+
```
|
|
854
|
+
|
|
855
|
+
#### Call Intercept
|
|
856
|
+
|
|
857
|
+
**Read call intercept:**
|
|
858
|
+
```python
|
|
859
|
+
result = api.session.rest_get(f"{BASE}/telephony/config/locations/{loc_id}/intercept")
|
|
860
|
+
```
|
|
861
|
+
|
|
862
|
+
**Update call intercept:**
|
|
863
|
+
```python
|
|
864
|
+
body = {"enabled": True, "incoming": {"type": "INTERCEPT_ALL", "voicemailEnabled": True}}
|
|
865
|
+
api.session.rest_put(f"{BASE}/telephony/config/locations/{loc_id}/intercept", json=body)
|
|
866
|
+
```
|
|
867
|
+
|
|
868
|
+
**Available intercept phone numbers:**
|
|
869
|
+
```python
|
|
870
|
+
result = api.session.rest_get(
|
|
871
|
+
f"{BASE}/telephony/config/locations/{loc_id}/callIntercept/availableNumbers",
|
|
872
|
+
params={"max": 1000}
|
|
873
|
+
)
|
|
874
|
+
numbers = result.get("availableNumbers", [])
|
|
875
|
+
```
|
|
876
|
+
|
|
877
|
+
#### Music on Hold
|
|
878
|
+
|
|
879
|
+
**Read MoH settings:**
|
|
880
|
+
```python
|
|
881
|
+
result = api.session.rest_get(f"{BASE}/telephony/config/locations/{loc_id}/musicOnHold")
|
|
882
|
+
# {"mohEnabled": bool, "greeting": "SYSTEM"|"CUSTOM", "audioFile": {...}, "playlist": {...}}
|
|
883
|
+
```
|
|
884
|
+
|
|
885
|
+
**Update MoH:**
|
|
886
|
+
```python
|
|
887
|
+
body = {"mohEnabled": True, "greeting": "SYSTEM"}
|
|
888
|
+
api.session.rest_put(f"{BASE}/telephony/config/locations/{loc_id}/musicOnHold", json=body)
|
|
889
|
+
```
|
|
890
|
+
|
|
891
|
+
#### Emergency Callback Number (ECBN)
|
|
892
|
+
|
|
893
|
+
**Read ECBN:**
|
|
894
|
+
```python
|
|
895
|
+
result = api.session.rest_get(
|
|
896
|
+
f"{BASE}/telephony/config/locations/{loc_id}/features/emergencyCallbackNumber"
|
|
897
|
+
)
|
|
898
|
+
```
|
|
899
|
+
|
|
900
|
+
**Update ECBN:**
|
|
901
|
+
```python
|
|
902
|
+
body = {"selected": "LOCATION_NUMBER"}
|
|
903
|
+
# Or: {"selected": "LOCATION_MEMBER_NUMBER", "locationMemberId": member_id}
|
|
904
|
+
api.session.rest_put(
|
|
905
|
+
f"{BASE}/telephony/config/locations/{loc_id}/features/emergencyCallbackNumber", json=body
|
|
906
|
+
)
|
|
907
|
+
```
|
|
908
|
+
|
|
909
|
+
**ECBN available phone numbers:**
|
|
910
|
+
```python
|
|
911
|
+
result = api.session.rest_get(
|
|
912
|
+
f"{BASE}/telephony/config/locations/{loc_id}/emergencyCallbackNumber/availableNumbers",
|
|
913
|
+
params={"max": 1000}
|
|
914
|
+
)
|
|
915
|
+
```
|
|
916
|
+
|
|
917
|
+
#### Announcement Language
|
|
918
|
+
|
|
919
|
+
**Change announcement language for existing entities at a location:**
|
|
920
|
+
```python
|
|
921
|
+
body = {
|
|
922
|
+
"announcementLanguageCode": "en_us",
|
|
923
|
+
"agentEnabled": True, # change for people/workspaces
|
|
924
|
+
"serviceEnabled": True # change for features (AA, CQ, etc.)
|
|
925
|
+
}
|
|
926
|
+
api.session.rest_post(
|
|
927
|
+
f"{BASE}/telephony/config/locations/{loc_id}/actions/modifyAnnouncementLanguage/invoke",
|
|
928
|
+
json=body
|
|
929
|
+
)
|
|
930
|
+
```
|
|
931
|
+
|
|
932
|
+
> **Gotcha:** Use lowercase language codes (`en_us`, not `en_US`). The API rejects uppercase variants. Also, `announcementLanguage` may return `None` even when set -- this is a known API quirk.
|
|
933
|
+
|
|
934
|
+
#### Call Captions
|
|
935
|
+
|
|
936
|
+
**Read call captions settings:**
|
|
937
|
+
```python
|
|
938
|
+
result = api.session.rest_get(f"{BASE}/telephony/config/locations/{loc_id}/callCaptions")
|
|
939
|
+
# {"locationClosedCaptionsEnabled", "locationTranscriptsEnabled",
|
|
940
|
+
# "orgClosedCaptionsEnabled", "orgTranscriptsEnabled", "useOrgSettingsEnabled"}
|
|
941
|
+
```
|
|
942
|
+
|
|
943
|
+
**Update call captions:**
|
|
944
|
+
```python
|
|
945
|
+
body = {
|
|
946
|
+
"locationClosedCaptionsEnabled": True,
|
|
947
|
+
"locationTranscriptsEnabled": True,
|
|
948
|
+
"useOrgSettingsEnabled": False
|
|
949
|
+
}
|
|
950
|
+
api.session.rest_put(f"{BASE}/telephony/config/locations/{loc_id}/callCaptions", json=body)
|
|
951
|
+
```
|
|
952
|
+
|
|
953
|
+
#### Device Settings
|
|
954
|
+
|
|
955
|
+
**Read location device overrides:**
|
|
956
|
+
```python
|
|
957
|
+
result = api.session.rest_get(f"{BASE}/telephony/config/locations/{loc_id}/devices/settings")
|
|
958
|
+
```
|
|
959
|
+
|
|
960
|
+
#### Safe Delete Check
|
|
961
|
+
|
|
962
|
+
**Check if location can be safely disabled:**
|
|
963
|
+
```python
|
|
964
|
+
result = api.session.rest_post(
|
|
965
|
+
f"{BASE}/telephony/config/locations/{loc_id}/actions/precheckForDeletion/invoke", json={}
|
|
966
|
+
)
|
|
967
|
+
# {"locationDeleteStatus": "BLOCKED"|"UNBLOCKED"|"FORCE_REQUIRED", "blocking": {...}, ...}
|
|
968
|
+
```
|
|
969
|
+
|
|
970
|
+
**Disable a calling location (async job):**
|
|
971
|
+
```python
|
|
972
|
+
body = {"locationId": loc_id, "locationName": "San Jose HQ", "forceDelete": False}
|
|
973
|
+
result = api.session.rest_post(
|
|
974
|
+
f"{BASE}/telephony/config/jobs/locations/deleteCallingLocation", json=body
|
|
975
|
+
)
|
|
976
|
+
job_id = result.get("id")
|
|
977
|
+
```
|
|
978
|
+
|
|
979
|
+
**Job management:**
|
|
980
|
+
```python
|
|
981
|
+
# List jobs
|
|
982
|
+
api.session.rest_get(f"{BASE}/telephony/config/jobs/locations/deleteCallingLocation")
|
|
983
|
+
# Get job status
|
|
984
|
+
api.session.rest_get(f"{BASE}/telephony/config/jobs/locations/deleteCallingLocation/{job_id}")
|
|
985
|
+
# Get job errors
|
|
986
|
+
api.session.rest_get(f"{BASE}/telephony/config/jobs/locations/deleteCallingLocation/{job_id}/errors")
|
|
987
|
+
# Pause job
|
|
988
|
+
api.session.rest_post(f"{BASE}/telephony/config/jobs/locations/deleteCallingLocation/{job_id}/actions/pause/invoke", json={})
|
|
989
|
+
# Resume job
|
|
990
|
+
api.session.rest_post(f"{BASE}/telephony/config/jobs/locations/deleteCallingLocation/{job_id}/actions/resume/invoke", json={})
|
|
991
|
+
```
|
|
992
|
+
|
|
993
|
+
#### CLI Examples — Disable Calling Location Jobs
|
|
994
|
+
|
|
995
|
+
```bash
|
|
996
|
+
# Safe delete check before disabling a location
|
|
997
|
+
wxcli location-settings safe-delete-check Y2lzY29zcGFyazovL...
|
|
998
|
+
|
|
999
|
+
# Disable a calling location
|
|
1000
|
+
wxcli location-settings create-delete-calling-location \
|
|
1001
|
+
--location-id Y2lzY29zcGFyazovL... \
|
|
1002
|
+
--location-name "San Jose HQ"
|
|
1003
|
+
|
|
1004
|
+
# Force-disable a calling location (when features like trunks exist)
|
|
1005
|
+
wxcli location-settings create-delete-calling-location \
|
|
1006
|
+
--location-id Y2lzY29zcGFyazovL... \
|
|
1007
|
+
--location-name "San Jose HQ" \
|
|
1008
|
+
--force-delete
|
|
1009
|
+
|
|
1010
|
+
# List disable calling location jobs
|
|
1011
|
+
wxcli location-settings list-delete-calling-location
|
|
1012
|
+
|
|
1013
|
+
# Get disable calling location job status
|
|
1014
|
+
wxcli location-settings show-delete-calling-location JOB_ID
|
|
1015
|
+
|
|
1016
|
+
# Get job errors
|
|
1017
|
+
wxcli location-settings list-errors JOB_ID
|
|
1018
|
+
|
|
1019
|
+
# Pause a job
|
|
1020
|
+
wxcli location-settings pause-a-disable JOB_ID
|
|
1021
|
+
|
|
1022
|
+
# Resume a paused job
|
|
1023
|
+
wxcli location-settings resume-a-paused JOB_ID
|
|
1024
|
+
```
|
|
1025
|
+
|
|
1026
|
+
#### Extension Validation
|
|
1027
|
+
|
|
1028
|
+
**Validate extensions at a location:**
|
|
1029
|
+
```python
|
|
1030
|
+
body = {"extensions": ["1000", "1001", "1002"]}
|
|
1031
|
+
result = api.session.rest_post(
|
|
1032
|
+
f"{BASE}/telephony/config/locations/{loc_id}/actions/validateExtensions/invoke", json=body
|
|
1033
|
+
)
|
|
1034
|
+
```
|
|
1035
|
+
|
|
1036
|
+
**Validate extensions org-wide:**
|
|
1037
|
+
```python
|
|
1038
|
+
body = {"extensions": ["1000", "1001"]}
|
|
1039
|
+
result = api.session.rest_post(
|
|
1040
|
+
f"{BASE}/telephony/config/actions/validateExtensions/invoke", json=body
|
|
1041
|
+
)
|
|
1042
|
+
```
|
|
1043
|
+
|
|
1044
|
+
#### Private Network Connect
|
|
1045
|
+
|
|
1046
|
+
**Read PNC settings:**
|
|
1047
|
+
```python
|
|
1048
|
+
result = api.session.rest_get(f"{BASE}/telephony/config/locations/{loc_id}/privateNetworkConnect")
|
|
1049
|
+
```
|
|
1050
|
+
|
|
1051
|
+
**Update PNC settings:**
|
|
1052
|
+
```python
|
|
1053
|
+
body = {"networkConnectionType": "PRIVATE_NETWORK"}
|
|
1054
|
+
api.session.rest_put(f"{BASE}/telephony/config/locations/{loc_id}/privateNetworkConnect", json=body)
|
|
1055
|
+
```
|
|
1056
|
+
|
|
1057
|
+
#### CLI Examples — Private Network Connect
|
|
1058
|
+
|
|
1059
|
+
```bash
|
|
1060
|
+
# Read private network connect settings
|
|
1061
|
+
wxcli location-settings show-private-network-connect Y2lzY29zcGFyazovL...
|
|
1062
|
+
|
|
1063
|
+
# Update private network connect
|
|
1064
|
+
wxcli location-settings update-private-network-connect Y2lzY29zcGFyazovL... \
|
|
1065
|
+
--json-body '{"networkConnectionType": "PRIVATE_NETWORK"}'
|
|
1066
|
+
```
|
|
1067
|
+
|
|
1068
|
+
#### Routing Prefix Jobs
|
|
1069
|
+
|
|
1070
|
+
**List update routing prefix jobs:**
|
|
1071
|
+
```python
|
|
1072
|
+
result = api.session.rest_get(f"{BASE}/telephony/config/jobs/updateRoutingPrefix")
|
|
1073
|
+
```
|
|
1074
|
+
|
|
1075
|
+
**Get job status / errors:**
|
|
1076
|
+
```python
|
|
1077
|
+
api.session.rest_get(f"{BASE}/telephony/config/jobs/updateRoutingPrefix/{job_id}")
|
|
1078
|
+
api.session.rest_get(f"{BASE}/telephony/config/jobs/updateRoutingPrefix/{job_id}/errors")
|
|
1079
|
+
```
|
|
1080
|
+
|
|
1081
|
+
#### Available Phone Numbers
|
|
1082
|
+
|
|
1083
|
+
Several endpoints return available phone numbers for different purposes. All follow the same pattern:
|
|
1084
|
+
|
|
1085
|
+
| Purpose | URL path |
|
|
1086
|
+
|---------|----------|
|
|
1087
|
+
| External Caller ID | `telephony/config/locations/{locId}/externalCallerId/availableNumbers` |
|
|
1088
|
+
| Location main number | `telephony/config/locations/{locId}/availableNumbers` |
|
|
1089
|
+
| Webex Go | `telephony/config/locations/{locId}/webexGo/availableNumbers` |
|
|
1090
|
+
| ECBN | `telephony/config/locations/{locId}/emergencyCallbackNumber/availableNumbers` |
|
|
1091
|
+
| Call Intercept | `telephony/config/locations/{locId}/callIntercept/availableNumbers` |
|
|
1092
|
+
| Charge Number | `telephony/config/locations/{locId}/chargeNumber/availableNumbers` |
|
|
1093
|
+
| Route Choices | `telephony/config/routeChoices` |
|
|
1094
|
+
|
|
1095
|
+
All accept `max`, `start`, `phoneNumber`, `ownerName` query params (availability varies by endpoint).
|
|
1096
|
+
|
|
1097
|
+
#### CLI Examples — Available Phone Numbers
|
|
1098
|
+
|
|
1099
|
+
```bash
|
|
1100
|
+
# List phone numbers available for external caller ID
|
|
1101
|
+
wxcli location-settings list-available-numbers-external-caller-id Y2lzY29zcGFyazovL...
|
|
1102
|
+
|
|
1103
|
+
# List available phone numbers for a location's main number
|
|
1104
|
+
wxcli location-settings list-available-numbers-locations Y2lzY29zcGFyazovL...
|
|
1105
|
+
|
|
1106
|
+
# List Webex Go available phone numbers
|
|
1107
|
+
wxcli location-settings list-available-numbers-webex-go Y2lzY29zcGFyazovL...
|
|
1108
|
+
|
|
1109
|
+
# List available charge numbers
|
|
1110
|
+
wxcli location-settings list-available-numbers-charge-number Y2lzY29zcGFyazovL...
|
|
1111
|
+
|
|
1112
|
+
# List route choices
|
|
1113
|
+
wxcli location-settings list-route-choices
|
|
1114
|
+
```
|
|
1115
|
+
|
|
1116
|
+
#### Receptionist Contact Directories
|
|
1117
|
+
|
|
1118
|
+
**Create directory:**
|
|
1119
|
+
```python
|
|
1120
|
+
body = {"name": "Front Desk Contacts", "contacts": [{"id": person_id}]}
|
|
1121
|
+
result = api.session.rest_post(
|
|
1122
|
+
f"{BASE}/telephony/config/locations/{loc_id}/receptionistContacts/directories", json=body
|
|
1123
|
+
)
|
|
1124
|
+
new_id = result.get("id")
|
|
1125
|
+
```
|
|
1126
|
+
|
|
1127
|
+
**List directories:**
|
|
1128
|
+
```python
|
|
1129
|
+
result = api.session.rest_get(
|
|
1130
|
+
f"{BASE}/telephony/config/locations/{loc_id}/receptionistContacts/directories"
|
|
1131
|
+
)
|
|
1132
|
+
dirs = result.get("directories", [])
|
|
1133
|
+
```
|
|
1134
|
+
|
|
1135
|
+
**Get directory details:**
|
|
1136
|
+
```python
|
|
1137
|
+
result = api.session.rest_get(
|
|
1138
|
+
f"{BASE}/telephony/config/locations/{loc_id}/receptionistContacts/directories/{dir_id}"
|
|
1139
|
+
)
|
|
1140
|
+
```
|
|
1141
|
+
|
|
1142
|
+
**Update directory (full replacement):**
|
|
1143
|
+
```python
|
|
1144
|
+
body = {"name": "Updated Name", "contacts": [{"id": person_id_1}, {"id": person_id_2}]}
|
|
1145
|
+
api.session.rest_put(
|
|
1146
|
+
f"{BASE}/telephony/config/locations/{loc_id}/receptionistContacts/directories/{dir_id}",
|
|
1147
|
+
json=body
|
|
1148
|
+
)
|
|
1149
|
+
```
|
|
1150
|
+
|
|
1151
|
+
**Delete directory:**
|
|
1152
|
+
```python
|
|
1153
|
+
api.session.rest_delete(
|
|
1154
|
+
f"{BASE}/telephony/config/locations/{loc_id}/receptionistContacts/directories/{dir_id}"
|
|
1155
|
+
)
|
|
1156
|
+
```
|
|
1157
|
+
|
|
1158
|
+
#### CLI Examples — Receptionist Contact Directories
|
|
1159
|
+
|
|
1160
|
+
```bash
|
|
1161
|
+
# List receptionist contact directories for a location
|
|
1162
|
+
wxcli location-settings list-directories Y2lzY29zcGFyazovL...
|
|
1163
|
+
|
|
1164
|
+
# Get details for a specific directory
|
|
1165
|
+
wxcli location-settings show-directories Y2lzY29zcGFyazovL... --json-body '...'
|
|
1166
|
+
|
|
1167
|
+
# Create a new receptionist contact directory
|
|
1168
|
+
wxcli location-settings create-directories Y2lzY29zcGFyazovL... \
|
|
1169
|
+
--json-body '{"name": "Front Desk Contacts", "contacts": [{"id": "PERSON_ID"}]}'
|
|
1170
|
+
|
|
1171
|
+
# Update a directory (full replacement of contacts)
|
|
1172
|
+
wxcli location-settings update-directories Y2lzY29zcGFyazovL... \
|
|
1173
|
+
--json-body '{"name": "Updated Name", "contacts": [{"id": "PERSON_ID_1"}, {"id": "PERSON_ID_2"}]}'
|
|
1174
|
+
|
|
1175
|
+
# Delete a receptionist contact directory
|
|
1176
|
+
wxcli location-settings delete Y2lzY29zcGFyazovL...
|
|
1177
|
+
```
|
|
1178
|
+
|
|
1179
|
+
---
|
|
1180
|
+
|
|
1181
|
+
### Additional Location-Level APIs on TelephonyLocationApi
|
|
1182
|
+
|
|
1183
|
+
#### `phone_numbers`
|
|
1184
|
+
|
|
1185
|
+
List service and standard PSTN numbers available to be assigned as the location's main number.
|
|
1186
|
+
|
|
1187
|
+
```python
|
|
1188
|
+
def phone_numbers(
|
|
1189
|
+
self,
|
|
1190
|
+
location_id: str,
|
|
1191
|
+
phone_number: List[str] = None,
|
|
1192
|
+
owner_name: str = None,
|
|
1193
|
+
org_id: str = None,
|
|
1194
|
+
**params
|
|
1195
|
+
) -> Generator[AvailableNumber, None, None]
|
|
1196
|
+
```
|
|
1197
|
+
|
|
1198
|
+
#### `webex_go_available_phone_numbers`
|
|
1199
|
+
|
|
1200
|
+
List standard numbers available for Webex Go assignment at a location.
|
|
1201
|
+
|
|
1202
|
+
```python
|
|
1203
|
+
def webex_go_available_phone_numbers(
|
|
1204
|
+
self,
|
|
1205
|
+
location_id: str,
|
|
1206
|
+
phone_number: List[str] = None,
|
|
1207
|
+
org_id: str = None,
|
|
1208
|
+
**params
|
|
1209
|
+
) -> Generator[AvailableNumber, None, None]
|
|
1210
|
+
```
|
|
1211
|
+
|
|
1212
|
+
#### `charge_number_available_phone_numbers`
|
|
1213
|
+
|
|
1214
|
+
List non-toll-free, non-mobile numbers available as the location's charge number.
|
|
1215
|
+
|
|
1216
|
+
```python
|
|
1217
|
+
def charge_number_available_phone_numbers(
|
|
1218
|
+
self,
|
|
1219
|
+
location_id: str,
|
|
1220
|
+
phone_number: List[str] = None,
|
|
1221
|
+
owner_name: str = None,
|
|
1222
|
+
org_id: str = None,
|
|
1223
|
+
**params
|
|
1224
|
+
) -> Generator[AvailableNumber, None, None]
|
|
1225
|
+
```
|
|
1226
|
+
|
|
1227
|
+
#### Receptionist Contact Directories
|
|
1228
|
+
|
|
1229
|
+
These methods manage named directories of users and location features (Auto Attendant, Call Queue, Hunt Group, Single Number Reach, Paging Group):
|
|
1230
|
+
|
|
1231
|
+
```python
|
|
1232
|
+
def create_receptionist_contact_directory(location_id, name, contacts, org_id=None) -> str
|
|
1233
|
+
def list_receptionist_contact_directories(location_id, org_id=None) -> List[IdAndName]
|
|
1234
|
+
def receptionist_contact_directory_details(location_id, directory_id, ...) -> List[ContactDetails]
|
|
1235
|
+
def delete_receptionist_contact_directory(location_id, directory_id, org_id=None)
|
|
1236
|
+
def modify_receptionist_contact_directory(location_id, directory_id, name, contacts, org_id=None) -> str
|
|
1237
|
+
```
|
|
1238
|
+
|
|
1239
|
+
Note: `modify` performs a **full replacement** of the contacts list (not incremental). The details API is supported for orgs with fewer than 2000 users or location-based calling features; orgs exceeding this threshold get error 25395.
|
|
1240
|
+
|
|
1241
|
+
---
|
|
1242
|
+
|
|
1243
|
+
## 2. Voicemail Policies
|
|
1244
|
+
|
|
1245
|
+
### Location Voicemail Settings
|
|
1246
|
+
|
|
1247
|
+
**API path:** `api.telephony.location.voicemail`
|
|
1248
|
+
|
|
1249
|
+
**Source:** `wxc_sdk.telephony.location.vm`
|
|
1250
|
+
|
|
1251
|
+
Currently limited to enabling/disabling voicemail transcription at the location level.
|
|
1252
|
+
|
|
1253
|
+
#### `LocationVoiceMailSettings` Model
|
|
1254
|
+
|
|
1255
|
+
| Field | Type | Description |
|
|
1256
|
+
|-------|------|-------------|
|
|
1257
|
+
| `voicemail_transcription_enabled` | `bool` | Enable/disable voicemail transcription for the location |
|
|
1258
|
+
|
|
1259
|
+
#### `read`
|
|
1260
|
+
|
|
1261
|
+
```python
|
|
1262
|
+
def read(
|
|
1263
|
+
self,
|
|
1264
|
+
location_id: str,
|
|
1265
|
+
org_id: str = None
|
|
1266
|
+
) -> LocationVoiceMailSettings
|
|
1267
|
+
```
|
|
1268
|
+
|
|
1269
|
+
**Scope:** `spark-admin:telephony_config_read`
|
|
1270
|
+
|
|
1271
|
+
#### `update`
|
|
1272
|
+
|
|
1273
|
+
```python
|
|
1274
|
+
def update(
|
|
1275
|
+
self,
|
|
1276
|
+
location_id: str,
|
|
1277
|
+
settings: LocationVoiceMailSettings,
|
|
1278
|
+
org_id: str = None
|
|
1279
|
+
)
|
|
1280
|
+
```
|
|
1281
|
+
|
|
1282
|
+
**Scope:** `spark-admin:telephony_config_write`
|
|
1283
|
+
|
|
1284
|
+
#### CLI Examples
|
|
1285
|
+
|
|
1286
|
+
```bash
|
|
1287
|
+
# Read location voicemail settings
|
|
1288
|
+
wxcli location-voicemail show Y2lzY29zcGFyazovL...
|
|
1289
|
+
|
|
1290
|
+
# Enable voicemail transcription for a location
|
|
1291
|
+
wxcli location-voicemail update Y2lzY29zcGFyazovL... --voicemail-transcription-enabled
|
|
1292
|
+
|
|
1293
|
+
# Disable voicemail transcription
|
|
1294
|
+
wxcli location-voicemail update Y2lzY29zcGFyazovL... --no-voicemail-transcription-enabled
|
|
1295
|
+
```
|
|
1296
|
+
|
|
1297
|
+
---
|
|
1298
|
+
|
|
1299
|
+
### Raw HTTP — Location Voicemail
|
|
1300
|
+
<!-- Updated by playbook session 2026-03-18 -->
|
|
1301
|
+
|
|
1302
|
+
**Read location voicemail settings:**
|
|
1303
|
+
```python
|
|
1304
|
+
result = api.session.rest_get(f"{BASE}/telephony/config/locations/{loc_id}/voicemail")
|
|
1305
|
+
# {"voicemailTranscriptionEnabled": bool}
|
|
1306
|
+
```
|
|
1307
|
+
|
|
1308
|
+
**Update location voicemail:**
|
|
1309
|
+
```python
|
|
1310
|
+
body = {"voicemailTranscriptionEnabled": True}
|
|
1311
|
+
api.session.rest_put(f"{BASE}/telephony/config/locations/{loc_id}/voicemail", json=body)
|
|
1312
|
+
```
|
|
1313
|
+
|
|
1314
|
+
---
|
|
1315
|
+
|
|
1316
|
+
### Organisation Voicemail Settings
|
|
1317
|
+
|
|
1318
|
+
**API path:** `api.telephony.organisation_voicemail`
|
|
1319
|
+
|
|
1320
|
+
**Source:** `wxc_sdk.telephony.organisation_vm`
|
|
1321
|
+
|
|
1322
|
+
**Base endpoint:** `telephony/config/voicemail/settings`
|
|
1323
|
+
|
|
1324
|
+
Controls org-wide voicemail message expiry and forwarding policies.
|
|
1325
|
+
|
|
1326
|
+
#### `OrganisationVoicemailSettings` Model
|
|
1327
|
+
|
|
1328
|
+
| Field | Type | Description |
|
|
1329
|
+
|-------|------|-------------|
|
|
1330
|
+
| `message_expiry_enabled` | `bool` | Enable deletion conditions for expired messages |
|
|
1331
|
+
| `number_of_days_for_message_expiry` | `int` | Days after which messages expire |
|
|
1332
|
+
| `strict_deletion_enabled` | `bool` | When enabled, both read and unread messages are deleted based on expiry. When disabled, unread messages are kept. |
|
|
1333
|
+
| `voice_message_forwarding_enabled` | `bool` | Allow people to configure email forwarding of voicemails |
|
|
1334
|
+
|
|
1335
|
+
**Defaults** (from `OrganisationVoicemailSettings.default()`):
|
|
1336
|
+
```python
|
|
1337
|
+
message_expiry_enabled = False
|
|
1338
|
+
number_of_days_for_message_expiry = 15
|
|
1339
|
+
strict_deletion_enabled = False
|
|
1340
|
+
voice_message_forwarding_enabled = False
|
|
1341
|
+
```
|
|
1342
|
+
|
|
1343
|
+
#### `read`
|
|
1344
|
+
|
|
1345
|
+
```python
|
|
1346
|
+
def read(
|
|
1347
|
+
self,
|
|
1348
|
+
org_id: str = None
|
|
1349
|
+
) -> OrganisationVoicemailSettings
|
|
1350
|
+
```
|
|
1351
|
+
|
|
1352
|
+
**Scope:** `spark-admin:telephony_config_read`
|
|
1353
|
+
|
|
1354
|
+
#### `update`
|
|
1355
|
+
|
|
1356
|
+
```python
|
|
1357
|
+
def update(
|
|
1358
|
+
self,
|
|
1359
|
+
settings: OrganisationVoicemailSettings,
|
|
1360
|
+
org_id: str = None
|
|
1361
|
+
)
|
|
1362
|
+
```
|
|
1363
|
+
|
|
1364
|
+
**Scope:** `spark-admin:telephony_config_write`
|
|
1365
|
+
|
|
1366
|
+
---
|
|
1367
|
+
|
|
1368
|
+
### Raw HTTP — Organisation Voicemail
|
|
1369
|
+
<!-- Updated by playbook session 2026-03-18 -->
|
|
1370
|
+
|
|
1371
|
+
**Read org voicemail settings:**
|
|
1372
|
+
```python
|
|
1373
|
+
result = api.session.rest_get(f"{BASE}/telephony/config/voicemail/settings")
|
|
1374
|
+
# {"messageExpiryEnabled", "numberOfDaysForMessageExpiry", "strictDeletionEnabled",
|
|
1375
|
+
# "voiceMessageForwardingEnabled"}
|
|
1376
|
+
```
|
|
1377
|
+
|
|
1378
|
+
**Update org voicemail settings:**
|
|
1379
|
+
```python
|
|
1380
|
+
body = {
|
|
1381
|
+
"messageExpiryEnabled": True,
|
|
1382
|
+
"numberOfDaysForMessageExpiry": 30,
|
|
1383
|
+
"strictDeletionEnabled": False,
|
|
1384
|
+
"voiceMessageForwardingEnabled": True
|
|
1385
|
+
}
|
|
1386
|
+
api.session.rest_put(f"{BASE}/telephony/config/voicemail/settings", json=body)
|
|
1387
|
+
```
|
|
1388
|
+
|
|
1389
|
+
---
|
|
1390
|
+
|
|
1391
|
+
## 3. Voicemail Rules (Org-Level Passcode Policy)
|
|
1392
|
+
|
|
1393
|
+
**API path:** `api.telephony.voicemail_rules`
|
|
1394
|
+
|
|
1395
|
+
**Source:** `wxc_sdk.telephony.vm_rules`
|
|
1396
|
+
|
|
1397
|
+
**Base endpoint:** `telephony/config/voicemail/rules`
|
|
1398
|
+
|
|
1399
|
+
Defines org-wide default voicemail passcode requirements.
|
|
1400
|
+
|
|
1401
|
+
### `VoiceMailRules` Model
|
|
1402
|
+
|
|
1403
|
+
| Field | Type | Description |
|
|
1404
|
+
|-------|------|-------------|
|
|
1405
|
+
| `default_voicemail_pin_rules` | `DefaultVoicemailPinRules` | Read-only rules (excluded from update payload) |
|
|
1406
|
+
| `default_voicemail_pin_enabled` | `bool` | Enable setting a default pin for new users (update only) |
|
|
1407
|
+
| `default_voicemail_pin` | `str` | The default pin value (update only) |
|
|
1408
|
+
| `expire_passcode` | `EnabledAndNumberOfDays` | Passcode expiry settings |
|
|
1409
|
+
| `change_passcode` | `EnabledAndNumberOfDays` | Minimum days before passcode can be changed |
|
|
1410
|
+
| `block_previous_passcodes` | `BlockPreviousPasscodes` | Block reuse of N previous passcodes |
|
|
1411
|
+
|
|
1412
|
+
### `DefaultVoicemailPinRules` Model (read-only)
|
|
1413
|
+
|
|
1414
|
+
| Field | Type | Description |
|
|
1415
|
+
|-------|------|-------------|
|
|
1416
|
+
| `block_repeated_patterns_enabled` | `bool` | Block repeated patterns |
|
|
1417
|
+
| `block_repeated_digits` | `BlockRepeatedDigits` | Block repeated digit groups (enabled, max) |
|
|
1418
|
+
| `block_contiguous_sequences` | `BlockContiguousSequences` | Block ascending/descending sequences (enabled, ascending count, descending count) |
|
|
1419
|
+
| `length` | `PinLength` | Min/max passcode length |
|
|
1420
|
+
| `default_voicemail_pin_enabled` | `bool` | Whether default pin is enabled |
|
|
1421
|
+
|
|
1422
|
+
### Supporting Models
|
|
1423
|
+
|
|
1424
|
+
#### `BlockRepeatedDigits`
|
|
1425
|
+
|
|
1426
|
+
| Field | Type | Range | Description |
|
|
1427
|
+
|-------|------|-------|-------------|
|
|
1428
|
+
| `enabled` | `bool` | | Block repeated digits |
|
|
1429
|
+
| `max` | `int` | 1-6 | Max repeated digits allowed |
|
|
1430
|
+
|
|
1431
|
+
#### `BlockContiguousSequences`
|
|
1432
|
+
|
|
1433
|
+
| Field | Type | Range | Description |
|
|
1434
|
+
|-------|------|-------|-------------|
|
|
1435
|
+
| `enabled` | `bool` | | Block sequential digits |
|
|
1436
|
+
| `number_of_ascending_digits` | `int` | 2-5 | Ascending sequence length to block |
|
|
1437
|
+
| `number_of_descending_digits` | `int` | 2-5 | Descending sequence length to block |
|
|
1438
|
+
|
|
1439
|
+
#### `PinLength`
|
|
1440
|
+
|
|
1441
|
+
| Field | Type | Range | Description |
|
|
1442
|
+
|-------|------|-------|-------------|
|
|
1443
|
+
| `min` | `int` | 2-15 | Minimum passcode length |
|
|
1444
|
+
| `max` | `int` | 3-30 | Maximum passcode length |
|
|
1445
|
+
|
|
1446
|
+
#### `BlockPreviousPasscodes`
|
|
1447
|
+
|
|
1448
|
+
| Field | Type | Range | Description |
|
|
1449
|
+
|-------|------|-------|-------------|
|
|
1450
|
+
| `enabled` | `bool` | | Block reuse of previous passcodes |
|
|
1451
|
+
| `number_of_passcodes` | `int` | 1-10 | How many previous passcodes to block |
|
|
1452
|
+
|
|
1453
|
+
#### `EnabledAndNumberOfDays`
|
|
1454
|
+
|
|
1455
|
+
| Field | Type | Description |
|
|
1456
|
+
|-------|------|-------------|
|
|
1457
|
+
| `enabled` | `bool` | Feature on/off |
|
|
1458
|
+
| `number_of_days` | `int` | Number of days for expiry/change window |
|
|
1459
|
+
|
|
1460
|
+
### Defaults (from `VoiceMailRules.default()`)
|
|
1461
|
+
|
|
1462
|
+
```python
|
|
1463
|
+
expire_passcode: enabled=True, number_of_days=180
|
|
1464
|
+
change_passcode: enabled=False, number_of_days=1
|
|
1465
|
+
block_previous_passcodes: enabled=True, number_of_passcodes=10
|
|
1466
|
+
# Pin rules defaults:
|
|
1467
|
+
block_repeated_patterns: True
|
|
1468
|
+
block_repeated_digits: max=3
|
|
1469
|
+
block_contiguous_sequences: ascending=3, descending=3
|
|
1470
|
+
pin_length: min=6, max=30
|
|
1471
|
+
default_voicemail_pin: disabled
|
|
1472
|
+
```
|
|
1473
|
+
|
|
1474
|
+
### Methods
|
|
1475
|
+
|
|
1476
|
+
#### `read`
|
|
1477
|
+
|
|
1478
|
+
```python
|
|
1479
|
+
def read(
|
|
1480
|
+
self,
|
|
1481
|
+
org_id: str = None
|
|
1482
|
+
) -> VoiceMailRules
|
|
1483
|
+
```
|
|
1484
|
+
|
|
1485
|
+
**Scope:** `spark-admin:telephony_config_read`
|
|
1486
|
+
|
|
1487
|
+
#### `update`
|
|
1488
|
+
|
|
1489
|
+
```python
|
|
1490
|
+
def update(
|
|
1491
|
+
self,
|
|
1492
|
+
settings: VoiceMailRules,
|
|
1493
|
+
org_id: str = None
|
|
1494
|
+
)
|
|
1495
|
+
```
|
|
1496
|
+
|
|
1497
|
+
**Important:** The `default_voicemail_pin_rules` field is **excluded** from the update payload. To set a default pin, use `default_voicemail_pin_enabled` and `default_voicemail_pin` on the `VoiceMailRules` object directly. If you enable a default pin, communicate it to your users -- they must reset it before accessing voicemail.
|
|
1498
|
+
|
|
1499
|
+
**Scope:** `spark-admin:telephony_config_write`
|
|
1500
|
+
|
|
1501
|
+
---
|
|
1502
|
+
|
|
1503
|
+
### Raw HTTP — Voicemail Rules
|
|
1504
|
+
<!-- Updated by playbook session 2026-03-18 -->
|
|
1505
|
+
|
|
1506
|
+
**Read org voicemail passcode rules:**
|
|
1507
|
+
```python
|
|
1508
|
+
result = api.session.rest_get(f"{BASE}/telephony/config/voicemail/rules")
|
|
1509
|
+
# {"defaultVoicemailPinRules": {...}, "expirePasscode": {...},
|
|
1510
|
+
# "changePasscode": {...}, "blockPreviousPasscodes": {...}}
|
|
1511
|
+
```
|
|
1512
|
+
|
|
1513
|
+
**Update org voicemail rules:**
|
|
1514
|
+
```python
|
|
1515
|
+
body = {
|
|
1516
|
+
"defaultVoicemailPinEnabled": True,
|
|
1517
|
+
"defaultVoicemailPin": "654321",
|
|
1518
|
+
"expirePasscode": {"enabled": True, "numberOfDays": 90},
|
|
1519
|
+
"changePasscode": {"enabled": False, "numberOfDays": 1},
|
|
1520
|
+
"blockPreviousPasscodes": {"enabled": True, "numberOfPasscodes": 5}
|
|
1521
|
+
}
|
|
1522
|
+
api.session.rest_put(f"{BASE}/telephony/config/voicemail/rules", json=body)
|
|
1523
|
+
```
|
|
1524
|
+
|
|
1525
|
+
> **Gotcha:** The `defaultVoicemailPinRules` field is **read-only** and excluded from update payloads. Set default PINs via the top-level `defaultVoicemailPinEnabled` and `defaultVoicemailPin` fields instead.
|
|
1526
|
+
|
|
1527
|
+
---
|
|
1528
|
+
|
|
1529
|
+
## 4. Voice Messaging (User-Level)
|
|
1530
|
+
|
|
1531
|
+
**API path:** `api.telephony.voice_messaging`
|
|
1532
|
+
|
|
1533
|
+
**Source:** `wxc_sdk.telephony.voice_messaging`
|
|
1534
|
+
|
|
1535
|
+
**Base endpoint:** `telephony/voiceMessages`
|
|
1536
|
+
|
|
1537
|
+
User-scoped API (not admin). Handles voicemail message retrieval, deletion, and read/unread status. All GET operations require `spark:calls_read`; write operations require `spark:calls_write`.
|
|
1538
|
+
|
|
1539
|
+
### Models
|
|
1540
|
+
|
|
1541
|
+
#### `MessageSummary`
|
|
1542
|
+
|
|
1543
|
+
| Field | Type | Description |
|
|
1544
|
+
|-------|------|-------------|
|
|
1545
|
+
| `new_messages` | `int` | Count of unread voicemail messages |
|
|
1546
|
+
| `old_messages` | `int` | Count of read voicemail messages |
|
|
1547
|
+
| `new_urgent_messages` | `int` | Count of unread urgent messages |
|
|
1548
|
+
| `old_urgent_messages` | `int` | Count of read urgent messages |
|
|
1549
|
+
|
|
1550
|
+
#### `VoiceMessageDetails`
|
|
1551
|
+
|
|
1552
|
+
| Field | Type | Description |
|
|
1553
|
+
|-------|------|-------------|
|
|
1554
|
+
| `id` | `str` | Message identifier |
|
|
1555
|
+
| `duration` | `int` | Duration in seconds (not present for FAX) |
|
|
1556
|
+
| `calling_party` | `VoiceMailPartyInformation` | Who left the message |
|
|
1557
|
+
| `urgent` | `bool` | Urgent flag |
|
|
1558
|
+
| `confidential` | `bool` | Confidential flag |
|
|
1559
|
+
| `read` | `bool` | Whether the message has been read |
|
|
1560
|
+
| `fax_page_count` | `int` | Page count (FAX only) |
|
|
1561
|
+
| `created` | `str` | Timestamp of message creation |
|
|
1562
|
+
|
|
1563
|
+
#### `VoiceMailPartyInformation`
|
|
1564
|
+
|
|
1565
|
+
| Field | Type | Description |
|
|
1566
|
+
|-------|------|-------------|
|
|
1567
|
+
| `name` | `str` | Caller name (absent if privacy enabled) |
|
|
1568
|
+
| `number` | `str` | Caller number — digits, URI, or E.164 (absent if privacy enabled) |
|
|
1569
|
+
| `person_id` | `str` | Person ID (absent if privacy enabled) |
|
|
1570
|
+
| `place_id` | `str` | Place ID (absent if privacy enabled) |
|
|
1571
|
+
| `privacy_enabled` | `bool` | Whether privacy is on |
|
|
1572
|
+
|
|
1573
|
+
### Methods
|
|
1574
|
+
|
|
1575
|
+
#### `summary`
|
|
1576
|
+
|
|
1577
|
+
```python
|
|
1578
|
+
def summary(self) -> MessageSummary
|
|
1579
|
+
```
|
|
1580
|
+
|
|
1581
|
+
Get voicemail message counts. **Scope:** `spark:calls_read`
|
|
1582
|
+
|
|
1583
|
+
#### `list`
|
|
1584
|
+
|
|
1585
|
+
```python
|
|
1586
|
+
def list(
|
|
1587
|
+
self,
|
|
1588
|
+
line_owner_id: str = None,
|
|
1589
|
+
**params
|
|
1590
|
+
) -> Generator[VoiceMessageDetails, None, None]
|
|
1591
|
+
```
|
|
1592
|
+
|
|
1593
|
+
List all voicemail messages. `line_owner_id` supports secondary lines on shared devices.
|
|
1594
|
+
|
|
1595
|
+
**Scope:** `spark:calls_read`
|
|
1596
|
+
|
|
1597
|
+
#### `delete`
|
|
1598
|
+
|
|
1599
|
+
```python
|
|
1600
|
+
def delete(self, message_id: str)
|
|
1601
|
+
```
|
|
1602
|
+
|
|
1603
|
+
Delete a specific voicemail message. **Scope:** `spark:calls_write`
|
|
1604
|
+
|
|
1605
|
+
#### `mark_as_read`
|
|
1606
|
+
|
|
1607
|
+
```python
|
|
1608
|
+
def mark_as_read(
|
|
1609
|
+
self,
|
|
1610
|
+
message_id: str,
|
|
1611
|
+
line_owner_id: str = None
|
|
1612
|
+
)
|
|
1613
|
+
```
|
|
1614
|
+
|
|
1615
|
+
Mark a specific message (or all messages if `message_id` semantics allow) as read. **Scope:** `spark:calls_write`
|
|
1616
|
+
|
|
1617
|
+
#### `mark_as_unread`
|
|
1618
|
+
|
|
1619
|
+
```python
|
|
1620
|
+
def mark_as_unread(
|
|
1621
|
+
self,
|
|
1622
|
+
message_id: str,
|
|
1623
|
+
line_owner_id: str = None
|
|
1624
|
+
)
|
|
1625
|
+
```
|
|
1626
|
+
|
|
1627
|
+
Mark a specific message (or all messages) as unread. **Scope:** `spark:calls_write`
|
|
1628
|
+
|
|
1629
|
+
---
|
|
1630
|
+
|
|
1631
|
+
### Raw HTTP — Voice Messaging
|
|
1632
|
+
<!-- Updated by playbook session 2026-03-18 -->
|
|
1633
|
+
|
|
1634
|
+
Voice messaging is user-scoped (not admin). Uses `spark:calls_read` and `spark:calls_write` scopes.
|
|
1635
|
+
|
|
1636
|
+
**Get voicemail summary:**
|
|
1637
|
+
```python
|
|
1638
|
+
result = api.session.rest_get(f"{BASE}/telephony/voiceMessages/summary")
|
|
1639
|
+
# {"newMessages", "oldMessages", "newUrgentMessages", "oldUrgentMessages"}
|
|
1640
|
+
```
|
|
1641
|
+
|
|
1642
|
+
**List voicemail messages:**
|
|
1643
|
+
```python
|
|
1644
|
+
result = api.session.rest_get(f"{BASE}/telephony/voiceMessages", params={"max": 100})
|
|
1645
|
+
messages = result.get("items", [])
|
|
1646
|
+
```
|
|
1647
|
+
|
|
1648
|
+
**Delete a voicemail message:**
|
|
1649
|
+
```python
|
|
1650
|
+
api.session.rest_delete(f"{BASE}/telephony/voiceMessages/{message_id}")
|
|
1651
|
+
```
|
|
1652
|
+
|
|
1653
|
+
**Mark as read / unread:**
|
|
1654
|
+
```python
|
|
1655
|
+
api.session.rest_put(f"{BASE}/telephony/voiceMessages/{message_id}/markAsRead")
|
|
1656
|
+
api.session.rest_put(f"{BASE}/telephony/voiceMessages/{message_id}/markAsUnread")
|
|
1657
|
+
```
|
|
1658
|
+
|
|
1659
|
+
---
|
|
1660
|
+
|
|
1661
|
+
## 5. Voice Portal
|
|
1662
|
+
|
|
1663
|
+
**API path:** `api.telephony.voiceportal`
|
|
1664
|
+
|
|
1665
|
+
**Source:** `wxc_sdk.telephony.voiceportal`
|
|
1666
|
+
|
|
1667
|
+
**Base endpoint:** `telephony/config/locations/{locationId}/voicePortal`
|
|
1668
|
+
|
|
1669
|
+
Voice portals provide an interactive voice response (IVR) system so administrators can manage auto attendant announcements. Each location has one voice portal.
|
|
1670
|
+
|
|
1671
|
+
### `VoicePortalSettings` Model
|
|
1672
|
+
|
|
1673
|
+
| Field | Type | Description |
|
|
1674
|
+
|-------|------|-------------|
|
|
1675
|
+
| `portal_id` | `str` | Voice Portal ID (aliased from `id`) |
|
|
1676
|
+
| `name` | `str` | Voice Portal name |
|
|
1677
|
+
| `language` | `str` | Language for audio announcements (excluded from updates) |
|
|
1678
|
+
| `language_code` | `str` | Language code for voicemail group audio announcement |
|
|
1679
|
+
| `extension` | `str` | Extension of incoming call |
|
|
1680
|
+
| `phone_number` | `str` | Phone number of incoming call |
|
|
1681
|
+
| `first_name` | `str` | **Deprecated.** Use `direct_line_caller_id_name` and `dial_by_name` instead. |
|
|
1682
|
+
| `last_name` | `str` | **Deprecated.** Use `direct_line_caller_id_name` and `dial_by_name` instead. |
|
|
1683
|
+
| `direct_line_caller_id_name` | `DirectLineCallerIdName` | Caller ID name shown for this voice portal |
|
|
1684
|
+
| `dial_by_name` | `str` | Name used for dial-by-name functions |
|
|
1685
|
+
|
|
1686
|
+
### `PasscodeRules` Model
|
|
1687
|
+
|
|
1688
|
+
Voice portal passcode rules (separate from the org-level voicemail rules).
|
|
1689
|
+
|
|
1690
|
+
| Field | Type | Description |
|
|
1691
|
+
|-------|------|-------------|
|
|
1692
|
+
| `expire_passcode` | `ExpirePasscode` | Passcode expiry (enabled, days) |
|
|
1693
|
+
| `failed_attempts` | `FailedAttempts` | Lock after N failed attempts (enabled, attempts) |
|
|
1694
|
+
| `block_previous_passcodes` | `BlockPreviousPasscodes` | Block reuse of previous passcodes |
|
|
1695
|
+
| `block_repeated_digits` | `BlockRepeatedDigits` | Block repeated digit groups |
|
|
1696
|
+
| `block_contiguous_sequences` | `BlockContiguousSequences` | Block sequential digits |
|
|
1697
|
+
| `length` | `PinLength` | Min/max passcode length |
|
|
1698
|
+
| `block_reversed_user_number_enabled` | `bool` | Block reversed phone number/extension as passcode |
|
|
1699
|
+
| `block_user_number_enabled` | `bool` | Block user phone number/extension as passcode |
|
|
1700
|
+
| `block_repeated_patterns_enabled` | `bool` | Block repeated patterns |
|
|
1701
|
+
| `block_reversed_old_passcode_enabled` | `bool` | Block reversed old passcode |
|
|
1702
|
+
|
|
1703
|
+
### Methods
|
|
1704
|
+
|
|
1705
|
+
#### `read`
|
|
1706
|
+
|
|
1707
|
+
```python
|
|
1708
|
+
def read(
|
|
1709
|
+
self,
|
|
1710
|
+
location_id: str,
|
|
1711
|
+
org_id: str = None
|
|
1712
|
+
) -> VoicePortalSettings
|
|
1713
|
+
```
|
|
1714
|
+
|
|
1715
|
+
**Scope:** `spark-admin:telephony_config_read`
|
|
1716
|
+
|
|
1717
|
+
#### `update`
|
|
1718
|
+
|
|
1719
|
+
```python
|
|
1720
|
+
def update(
|
|
1721
|
+
self,
|
|
1722
|
+
location_id: str,
|
|
1723
|
+
settings: VoicePortalSettings,
|
|
1724
|
+
passcode: str = None,
|
|
1725
|
+
org_id: str = None
|
|
1726
|
+
)
|
|
1727
|
+
```
|
|
1728
|
+
|
|
1729
|
+
Update voice portal settings. Pass `passcode` to change the portal passcode (SDK sends both `newPasscode` and `confirmPasscode` automatically). The `portal_id` and `language` fields are excluded from the update payload.
|
|
1730
|
+
|
|
1731
|
+
**Scope:** `spark-admin:telephony_config_write`
|
|
1732
|
+
|
|
1733
|
+
#### `available_phone_numbers`
|
|
1734
|
+
|
|
1735
|
+
```python
|
|
1736
|
+
def available_phone_numbers(
|
|
1737
|
+
self,
|
|
1738
|
+
location_id: str,
|
|
1739
|
+
phone_number: list[str] = None,
|
|
1740
|
+
org_id: str = None,
|
|
1741
|
+
**params
|
|
1742
|
+
) -> Generator[AvailableNumber, None, None]
|
|
1743
|
+
```
|
|
1744
|
+
|
|
1745
|
+
List numbers available to be assigned as the voice portal's phone number.
|
|
1746
|
+
|
|
1747
|
+
**Scope:** `spark-admin:telephony_config_read`
|
|
1748
|
+
|
|
1749
|
+
#### `passcode_rules`
|
|
1750
|
+
|
|
1751
|
+
```python
|
|
1752
|
+
def passcode_rules(
|
|
1753
|
+
self,
|
|
1754
|
+
location_id: str,
|
|
1755
|
+
org_id: str = None
|
|
1756
|
+
) -> PasscodeRules
|
|
1757
|
+
```
|
|
1758
|
+
|
|
1759
|
+
Retrieve the voice portal passcode rules for a location.
|
|
1760
|
+
|
|
1761
|
+
**Scope:** `spark-admin:telephony_config_read`
|
|
1762
|
+
|
|
1763
|
+
#### CLI Examples
|
|
1764
|
+
|
|
1765
|
+
```bash
|
|
1766
|
+
# Read voice portal settings for a location
|
|
1767
|
+
wxcli location-voicemail show-voice-portal Y2lzY29zcGFyazovL...
|
|
1768
|
+
|
|
1769
|
+
# Update voice portal settings
|
|
1770
|
+
wxcli location-voicemail update-voice-portal Y2lzY29zcGFyazovL... \
|
|
1771
|
+
--name "Voice Portal" \
|
|
1772
|
+
--extension "9999" \
|
|
1773
|
+
--language-code "en_us" \
|
|
1774
|
+
--dial-by-name "Voice Portal"
|
|
1775
|
+
|
|
1776
|
+
# Read voice portal passcode rules
|
|
1777
|
+
wxcli location-voicemail show-passcode-rules Y2lzY29zcGFyazovL...
|
|
1778
|
+
|
|
1779
|
+
# List available phone numbers for voice portal
|
|
1780
|
+
wxcli location-voicemail list-available-numbers-voice-portal Y2lzY29zcGFyazovL...
|
|
1781
|
+
```
|
|
1782
|
+
|
|
1783
|
+
---
|
|
1784
|
+
|
|
1785
|
+
### Raw HTTP — Voice Portal
|
|
1786
|
+
<!-- Updated by playbook session 2026-03-18 -->
|
|
1787
|
+
|
|
1788
|
+
**Read voice portal settings:**
|
|
1789
|
+
```python
|
|
1790
|
+
result = api.session.rest_get(f"{BASE}/telephony/config/locations/{loc_id}/voicePortal")
|
|
1791
|
+
# {"id", "name", "languageCode", "extension", "phoneNumber", "firstName", "lastName",
|
|
1792
|
+
# "directLineCallerIdName", "dialByName"}
|
|
1793
|
+
```
|
|
1794
|
+
|
|
1795
|
+
**Update voice portal:**
|
|
1796
|
+
```python
|
|
1797
|
+
body = {
|
|
1798
|
+
"name": "Voice Portal",
|
|
1799
|
+
"extension": "9999",
|
|
1800
|
+
"languageCode": "en_us",
|
|
1801
|
+
"dialByName": "Voice Portal"
|
|
1802
|
+
}
|
|
1803
|
+
api.session.rest_put(f"{BASE}/telephony/config/locations/{loc_id}/voicePortal", json=body)
|
|
1804
|
+
```
|
|
1805
|
+
|
|
1806
|
+
> **Gotcha:** To change the portal passcode via raw HTTP, include `newPasscode` and `confirmPasscode` in the body (the SDK wraps this for you, but raw HTTP requires both fields).
|
|
1807
|
+
|
|
1808
|
+
**Read voice portal passcode rules:**
|
|
1809
|
+
```python
|
|
1810
|
+
result = api.session.rest_get(
|
|
1811
|
+
f"{BASE}/telephony/config/locations/{loc_id}/voicePortal/passcodeRules"
|
|
1812
|
+
)
|
|
1813
|
+
```
|
|
1814
|
+
|
|
1815
|
+
**Available phone numbers for voice portal:**
|
|
1816
|
+
```python
|
|
1817
|
+
result = api.session.rest_get(
|
|
1818
|
+
f"{BASE}/telephony/config/locations/{loc_id}/voicePortal/availableNumbers",
|
|
1819
|
+
params={"max": 1000}
|
|
1820
|
+
)
|
|
1821
|
+
numbers = result.get("availableNumbers", [])
|
|
1822
|
+
```
|
|
1823
|
+
|
|
1824
|
+
### Raw HTTP — Voicemail Groups
|
|
1825
|
+
<!-- Updated by playbook session 2026-03-18 -->
|
|
1826
|
+
|
|
1827
|
+
Voicemail groups are location-scoped features for shared voicemail boxes.
|
|
1828
|
+
|
|
1829
|
+
**List voicemail groups:**
|
|
1830
|
+
```python
|
|
1831
|
+
params = {"locationId": loc_id, "max": 1000}
|
|
1832
|
+
result = api.session.rest_get(f"{BASE}/telephony/config/voicemailGroups", params=params)
|
|
1833
|
+
groups = result.get("voicemailGroups", [])
|
|
1834
|
+
```
|
|
1835
|
+
|
|
1836
|
+
**Get voicemail group details:**
|
|
1837
|
+
```python
|
|
1838
|
+
result = api.session.rest_get(
|
|
1839
|
+
f"{BASE}/telephony/config/locations/{loc_id}/voicemailGroups/{vmg_id}"
|
|
1840
|
+
)
|
|
1841
|
+
```
|
|
1842
|
+
|
|
1843
|
+
**Create voicemail group:**
|
|
1844
|
+
```python
|
|
1845
|
+
body = {
|
|
1846
|
+
"name": "Sales VM Group",
|
|
1847
|
+
"extension": "2000",
|
|
1848
|
+
"passcode": "123456",
|
|
1849
|
+
"languageCode": "en_us"
|
|
1850
|
+
}
|
|
1851
|
+
result = api.session.rest_post(
|
|
1852
|
+
f"{BASE}/telephony/config/locations/{loc_id}/voicemailGroups", json=body
|
|
1853
|
+
)
|
|
1854
|
+
new_id = result.get("id")
|
|
1855
|
+
```
|
|
1856
|
+
|
|
1857
|
+
**Update voicemail group:**
|
|
1858
|
+
```python
|
|
1859
|
+
body = {"name": "Updated Sales VM", "enabled": True, "greeting": "CUSTOM"}
|
|
1860
|
+
api.session.rest_put(
|
|
1861
|
+
f"{BASE}/telephony/config/locations/{loc_id}/voicemailGroups/{vmg_id}", json=body
|
|
1862
|
+
)
|
|
1863
|
+
```
|
|
1864
|
+
|
|
1865
|
+
**Delete voicemail group:**
|
|
1866
|
+
```python
|
|
1867
|
+
api.session.rest_delete(
|
|
1868
|
+
f"{BASE}/telephony/config/locations/{loc_id}/voicemailGroups/{vmg_id}"
|
|
1869
|
+
)
|
|
1870
|
+
```
|
|
1871
|
+
|
|
1872
|
+
**Available phone numbers for voicemail groups:**
|
|
1873
|
+
```python
|
|
1874
|
+
# Regular available numbers
|
|
1875
|
+
api.session.rest_get(
|
|
1876
|
+
f"{BASE}/telephony/config/locations/{loc_id}/voicemailGroups/availableNumbers",
|
|
1877
|
+
params={"max": 1000}
|
|
1878
|
+
)
|
|
1879
|
+
# Fax message available numbers
|
|
1880
|
+
api.session.rest_get(
|
|
1881
|
+
f"{BASE}/telephony/config/locations/{loc_id}/voicemailGroups/faxMessage/availableNumbers",
|
|
1882
|
+
params={"max": 1000}
|
|
1883
|
+
)
|
|
1884
|
+
```
|
|
1885
|
+
|
|
1886
|
+
#### CLI Examples — Voicemail Groups
|
|
1887
|
+
|
|
1888
|
+
```bash
|
|
1889
|
+
# List voicemail groups for a location
|
|
1890
|
+
wxcli location-voicemail list --location-id Y2lzY29zcGFyazovL...
|
|
1891
|
+
|
|
1892
|
+
# Get voicemail group details
|
|
1893
|
+
wxcli location-voicemail show-voicemail-groups Y2lzY29zcGFyazovL...
|
|
1894
|
+
|
|
1895
|
+
# Create a voicemail group
|
|
1896
|
+
wxcli location-voicemail create Y2lzY29zcGFyazovL... \
|
|
1897
|
+
--name "Sales VM Group" \
|
|
1898
|
+
--extension "2000" \
|
|
1899
|
+
--passcode "123456" \
|
|
1900
|
+
--language-code "en_us"
|
|
1901
|
+
|
|
1902
|
+
# Update a voicemail group
|
|
1903
|
+
wxcli location-voicemail update-voicemail-groups Y2lzY29zcGFyazovL... \
|
|
1904
|
+
--json-body '{"name": "Updated Sales VM", "enabled": true}'
|
|
1905
|
+
|
|
1906
|
+
# Delete a voicemail group
|
|
1907
|
+
wxcli location-voicemail delete Y2lzY29zcGFyazovL...
|
|
1908
|
+
|
|
1909
|
+
# List available phone numbers for voicemail groups
|
|
1910
|
+
wxcli location-voicemail list-available-numbers-voicemail-groups Y2lzY29zcGFyazovL...
|
|
1911
|
+
|
|
1912
|
+
# List fax message available phone numbers
|
|
1913
|
+
wxcli location-voicemail list-available-numbers-fax-message Y2lzY29zcGFyazovL...
|
|
1914
|
+
```
|
|
1915
|
+
|
|
1916
|
+
---
|
|
1917
|
+
|
|
1918
|
+
## API Access Path Summary
|
|
1919
|
+
|
|
1920
|
+
| Setting | SDK Access Path | Scope |
|
|
1921
|
+
|---------|----------------|-------|
|
|
1922
|
+
| Location telephony details | `api.telephony.location.details()` | read |
|
|
1923
|
+
| Location list | `api.telephony.location.list()` | read |
|
|
1924
|
+
| Enable calling | `api.telephony.location.enable_for_calling()` | write |
|
|
1925
|
+
| Update location | `api.telephony.location.update()` | write |
|
|
1926
|
+
| Internal dialing | `api.telephony.location.internal_dialing.read/update()` | read/write |
|
|
1927
|
+
| Call intercept | `api.telephony.location.intercept.read/configure()` | read/write |
|
|
1928
|
+
| Music on hold | `api.telephony.location.moh.read/update()` | read/write |
|
|
1929
|
+
| Location numbers | `api.telephony.location.number.add/remove/activate/manage_number_state()` | write |
|
|
1930
|
+
| Location voicemail | `api.telephony.location.voicemail.read/update()` | read/write |
|
|
1931
|
+
| ECBN | `api.telephony.location.read_ecbn/update_ecbn()` | read/write |
|
|
1932
|
+
| Call captions | `api.telephony.location.get_call_captions_settings/update_call_captions_settings()` | read/write |
|
|
1933
|
+
| Announcement language | `api.telephony.location.change_announcement_language()` | write |
|
|
1934
|
+
| Device settings | `api.telephony.location.device_settings()` | read |
|
|
1935
|
+
| Safe delete check | `api.telephony.location.safe_delete_check_before_disabling_calling_location()` | read |
|
|
1936
|
+
| Org voicemail settings | `api.telephony.organisation_voicemail.read/update()` | read/write |
|
|
1937
|
+
| Voicemail rules | `api.telephony.voicemail_rules.read/update()` | read/write |
|
|
1938
|
+
| Voice messaging (user) | `api.telephony.voice_messaging.summary/list/delete/mark_as_read/mark_as_unread()` | calls_read/write |
|
|
1939
|
+
| Voice portal | `api.telephony.voiceportal.read/update/passcode_rules/available_phone_numbers()` | read/write |
|
|
1940
|
+
|
|
1941
|
+
---
|
|
1942
|
+
|
|
1943
|
+
## Raw HTTP URL Pattern Summary
|
|
1944
|
+
<!-- Updated by playbook session 2026-03-18 -->
|
|
1945
|
+
|
|
1946
|
+
| Area | URL Pattern | Methods |
|
|
1947
|
+
|------|-------------|---------|
|
|
1948
|
+
| Location calling config | `telephony/config/locations` | GET (list), POST (enable) |
|
|
1949
|
+
| Location details | `telephony/config/locations/{locId}` | GET, PUT |
|
|
1950
|
+
| Internal dialing | `telephony/config/locations/{locId}/internalDialing` | GET, PUT |
|
|
1951
|
+
| Call intercept | `telephony/config/locations/{locId}/intercept` | GET, PUT |
|
|
1952
|
+
| Music on hold | `telephony/config/locations/{locId}/musicOnHold` | GET, PUT |
|
|
1953
|
+
| ECBN | `telephony/config/locations/{locId}/features/emergencyCallbackNumber` | GET, PUT |
|
|
1954
|
+
| Call captions | `telephony/config/locations/{locId}/callCaptions` | GET, PUT |
|
|
1955
|
+
| Announcement language | `telephony/config/locations/{locId}/actions/modifyAnnouncementLanguage/invoke` | POST |
|
|
1956
|
+
| Private network connect | `telephony/config/locations/{locId}/privateNetworkConnect` | GET, PUT |
|
|
1957
|
+
| Safe delete precheck | `telephony/config/locations/{locId}/actions/precheckForDeletion/invoke` | POST |
|
|
1958
|
+
| Validate extensions | `telephony/config/locations/{locId}/actions/validateExtensions/invoke` | POST |
|
|
1959
|
+
| Validate extensions (org) | `telephony/config/actions/validateExtensions/invoke` | POST |
|
|
1960
|
+
| Location voicemail | `telephony/config/locations/{locId}/voicemail` | GET, PUT |
|
|
1961
|
+
| Voice portal | `telephony/config/locations/{locId}/voicePortal` | GET, PUT |
|
|
1962
|
+
| Voice portal passcode rules | `telephony/config/locations/{locId}/voicePortal/passcodeRules` | GET |
|
|
1963
|
+
| Org voicemail settings | `telephony/config/voicemail/settings` | GET, PUT |
|
|
1964
|
+
| Org voicemail rules | `telephony/config/voicemail/rules` | GET, PUT |
|
|
1965
|
+
| Voicemail groups (list) | `telephony/config/voicemailGroups` | GET |
|
|
1966
|
+
| Voicemail groups (CRUD) | `telephony/config/locations/{locId}/voicemailGroups/{vmgId}` | GET, PUT, DELETE |
|
|
1967
|
+
| Voicemail groups (create) | `telephony/config/locations/{locId}/voicemailGroups` | POST |
|
|
1968
|
+
| Receptionist directories | `telephony/config/locations/{locId}/receptionistContacts/directories` | GET, POST |
|
|
1969
|
+
| Receptionist directory | `telephony/config/locations/{locId}/receptionistContacts/directories/{dirId}` | GET, PUT, DELETE |
|
|
1970
|
+
| Delete calling location job | `telephony/config/jobs/locations/deleteCallingLocation` | GET, POST |
|
|
1971
|
+
| Routing prefix jobs | `telephony/config/jobs/updateRoutingPrefix` | GET |
|
|
1972
|
+
|
|
1973
|
+
## Raw HTTP Gotchas
|
|
1974
|
+
<!-- Updated by playbook session 2026-03-18 -->
|
|
1975
|
+
|
|
1976
|
+
1. **Lowercase language codes** -- The API rejects `en_US`; use `en_us` instead. Applies to both `announcementLanguage` on location updates and `announcementLanguageCode` on the language change action.
|
|
1977
|
+
2. **`announcementLanguage` returns None** -- Even when a language is set, the GET response may return `null` for this field. This is a known API quirk.
|
|
1978
|
+
3. **Voice portal passcode requires two fields** -- When changing passcode via raw HTTP, you must send both `newPasscode` and `confirmPasscode`. The SDK handles this automatically but raw HTTP does not.
|
|
1979
|
+
4. **Receptionist directory modify is full replacement** -- PUT on a directory replaces the entire contacts list. Always include the full desired contacts array.
|
|
1980
|
+
5. **No auto-pagination** -- All list endpoints require manual `max` and `start` params. Set `max=1000` for maximum page size.
|
|
1981
|
+
6. **Action endpoints use POST** -- `validateExtensions`, `modifyAnnouncementLanguage`, `precheckForDeletion`, job pause/resume all use POST, not GET or PUT.
|
|
1982
|
+
|
|
1983
|
+
## CLI: `calling-service` (Org-Level Calling Service Settings)
|
|
1984
|
+
|
|
1985
|
+
The `calling-service` CLI group covers org-level voicemail settings, voicemail rules, music on hold configuration, large organization status, and call captions. These are org-wide settings, not per-location.
|
|
1986
|
+
|
|
1987
|
+
| Command | Description |
|
|
1988
|
+
|---------|-------------|
|
|
1989
|
+
| `calling-service list` | List announcement languages |
|
|
1990
|
+
| `calling-service show` | Get org voicemail settings |
|
|
1991
|
+
| `calling-service update` | Update org voicemail settings |
|
|
1992
|
+
| `calling-service show-rules` | Get org voicemail rules (passcode policy) |
|
|
1993
|
+
| `calling-service update-rules` | Update org voicemail rules |
|
|
1994
|
+
| `calling-service show-settings` | Get org music on hold configuration |
|
|
1995
|
+
| `calling-service update-settings` | Update org music on hold configuration |
|
|
1996
|
+
| `calling-service show-large-org-status` | Get large organization status |
|
|
1997
|
+
| `calling-service show-call-captions` | Get org call captions settings |
|
|
1998
|
+
| `calling-service update-call-captions` | Update org call captions settings |
|
|
1999
|
+
|
|
2000
|
+
```bash
|
|
2001
|
+
# List available announcement languages
|
|
2002
|
+
wxcli calling-service list
|
|
2003
|
+
|
|
2004
|
+
# Get org-level voicemail settings
|
|
2005
|
+
wxcli calling-service show
|
|
2006
|
+
|
|
2007
|
+
# Enable voicemail message expiry after 30 days
|
|
2008
|
+
wxcli calling-service update --message-expiry-enabled --number-of-days-for-message-expiry 30
|
|
2009
|
+
|
|
2010
|
+
# Get org music on hold configuration
|
|
2011
|
+
wxcli calling-service show-settings
|
|
2012
|
+
|
|
2013
|
+
# Check if this org qualifies as a large organization
|
|
2014
|
+
wxcli calling-service show-large-org-status
|
|
2015
|
+
|
|
2016
|
+
# Get org call captions settings
|
|
2017
|
+
wxcli calling-service show-call-captions
|
|
2018
|
+
|
|
2019
|
+
# Enable org-level closed captions and transcripts
|
|
2020
|
+
wxcli calling-service update-call-captions --org-closed-captions-enabled --org-transcripts-enabled
|
|
2021
|
+
```
|
|
2022
|
+
|
|
2023
|
+
## CLI Groups
|
|
2024
|
+
|
|
2025
|
+
| CLI Group |
|
|
2026
|
+
|-----------|
|
|
2027
|
+
| `location-call-settings` |
|
|
2028
|
+
| `location-call-settings-voicemail` |
|
|
2029
|
+
| `calling-service` |
|
|
2030
|
+
|
|
2031
|
+
---
|
|
2032
|
+
|
|
2033
|
+
## See Also
|
|
2034
|
+
|
|
2035
|
+
- **[Person Call Settings — Handling](person-call-settings-handling.md)** — Per-user call forwarding overrides and call intercept settings that override location-level defaults
|
|
2036
|
+
- **[Person Call Settings — Media](person-call-settings-media.md)** — Per-user voicemail settings, music on hold overrides, and call intercept at the person level
|
|
2037
|
+
- **[Person Call Settings — Behavior](person-call-settings-behavior.md)** — Per-user ECBN settings that override the location ECBN default
|