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.
Files changed (413) hide show
  1. wxcli/__init__.py +4 -0
  2. wxcli/_playbook/.claude/agents/migration-advisor.md +239 -0
  3. wxcli/_playbook/.claude/agents/wxc-calling-builder.md +946 -0
  4. wxcli/_playbook/.claude/rules/cleanup.md +29 -0
  5. wxcli/_playbook/.claude/rules/cucm-migration.md +58 -0
  6. wxcli/_playbook/.claude/rules/org-health.md +14 -0
  7. wxcli/_playbook/.claude/settings.json +8 -0
  8. wxcli/_playbook/.claude/skills/audit-compliance/SKILL.md +515 -0
  9. wxcli/_playbook/.claude/skills/call-control/SKILL.md +747 -0
  10. wxcli/_playbook/.claude/skills/configure-features/SKILL.md +623 -0
  11. wxcli/_playbook/.claude/skills/configure-routing/SKILL.md +627 -0
  12. wxcli/_playbook/.claude/skills/contact-center/SKILL.md +1181 -0
  13. wxcli/_playbook/.claude/skills/cucm-migrate/SKILL.md +820 -0
  14. wxcli/_playbook/.claude/skills/customer-assist/SKILL.md +443 -0
  15. wxcli/_playbook/.claude/skills/device-platform/SKILL.md +407 -0
  16. wxcli/_playbook/.claude/skills/manage-call-settings/SKILL.md +757 -0
  17. wxcli/_playbook/.claude/skills/manage-devices/SKILL.md +790 -0
  18. wxcli/_playbook/.claude/skills/manage-identity/SKILL.md +638 -0
  19. wxcli/_playbook/.claude/skills/manage-licensing/SKILL.md +528 -0
  20. wxcli/_playbook/.claude/skills/manage-meetings/SKILL.md +708 -0
  21. wxcli/_playbook/.claude/skills/messaging-bots/SKILL.md +365 -0
  22. wxcli/_playbook/.claude/skills/messaging-spaces/SKILL.md +520 -0
  23. wxcli/_playbook/.claude/skills/org-health/SKILL.md +159 -0
  24. wxcli/_playbook/.claude/skills/provision-calling/SKILL.md +421 -0
  25. wxcli/_playbook/.claude/skills/query-live/SKILL.md +183 -0
  26. wxcli/_playbook/.claude/skills/query-live/domains/call-flow-trace.md +223 -0
  27. wxcli/_playbook/.claude/skills/query-live/domains/call-history.md +44 -0
  28. wxcli/_playbook/.claude/skills/query-live/domains/features.md +169 -0
  29. wxcli/_playbook/.claude/skills/query-live/domains/numbers.md +93 -0
  30. wxcli/_playbook/.claude/skills/query-live/domains/people-and-settings.md +146 -0
  31. wxcli/_playbook/.claude/skills/query-live/domains/routing.md +124 -0
  32. wxcli/_playbook/.claude/skills/reporting/SKILL.md +501 -0
  33. wxcli/_playbook/.claude/skills/reporting/references/cdr-recipes.md +1628 -0
  34. wxcli/_playbook/.claude/skills/reporting-cc/SKILL.md +251 -0
  35. wxcli/_playbook/.claude/skills/reporting-meetings/SKILL.md +290 -0
  36. wxcli/_playbook/.claude/skills/teardown/SKILL.md +214 -0
  37. wxcli/_playbook/.claude/skills/video-mesh/SKILL.md +379 -0
  38. wxcli/_playbook/.claude/skills/wxc-calling-debug/SKILL.md +475 -0
  39. wxcli/_playbook/CLAUDE.md +373 -0
  40. wxcli/_playbook/docs/reference/CLAUDE.md +25 -0
  41. wxcli/_playbook/docs/reference/admin-apps-data.md +643 -0
  42. wxcli/_playbook/docs/reference/admin-audit-security.md +322 -0
  43. wxcli/_playbook/docs/reference/admin-hybrid.md +383 -0
  44. wxcli/_playbook/docs/reference/admin-identity-scim.md +1007 -0
  45. wxcli/_playbook/docs/reference/admin-licensing.md +414 -0
  46. wxcli/_playbook/docs/reference/admin-org-management.md +586 -0
  47. wxcli/_playbook/docs/reference/admin-partner.md +357 -0
  48. wxcli/_playbook/docs/reference/archive/wxc-sdk-patterns.md +1229 -0
  49. wxcli/_playbook/docs/reference/archive/wxcadm-advanced.md +835 -0
  50. wxcli/_playbook/docs/reference/archive/wxcadm-core.md +743 -0
  51. wxcli/_playbook/docs/reference/archive/wxcadm-devices-workspaces.md +1305 -0
  52. wxcli/_playbook/docs/reference/archive/wxcadm-features.md +849 -0
  53. wxcli/_playbook/docs/reference/archive/wxcadm-locations.md +938 -0
  54. wxcli/_playbook/docs/reference/archive/wxcadm-person.md +1255 -0
  55. wxcli/_playbook/docs/reference/archive/wxcadm-routing.md +1262 -0
  56. wxcli/_playbook/docs/reference/authentication.md +965 -0
  57. wxcli/_playbook/docs/reference/call-control.md +1205 -0
  58. wxcli/_playbook/docs/reference/call-features-additional.md +2541 -0
  59. wxcli/_playbook/docs/reference/call-features-major.md +1320 -0
  60. wxcli/_playbook/docs/reference/call-routing.md +2304 -0
  61. wxcli/_playbook/docs/reference/contact-center-analytics.md +1049 -0
  62. wxcli/_playbook/docs/reference/contact-center-core.md +1614 -0
  63. wxcli/_playbook/docs/reference/contact-center-journey.md +457 -0
  64. wxcli/_playbook/docs/reference/contact-center-routing.md +1138 -0
  65. wxcli/_playbook/docs/reference/devices-core.md +1869 -0
  66. wxcli/_playbook/docs/reference/devices-dect.md +1150 -0
  67. wxcli/_playbook/docs/reference/devices-platform.md +467 -0
  68. wxcli/_playbook/docs/reference/devices-workspaces.md +1426 -0
  69. wxcli/_playbook/docs/reference/emergency-services.md +1122 -0
  70. wxcli/_playbook/docs/reference/location-calling-core.md +2037 -0
  71. wxcli/_playbook/docs/reference/location-calling-media.md +1334 -0
  72. wxcli/_playbook/docs/reference/location-recording-advanced.md +1482 -0
  73. wxcli/_playbook/docs/reference/meetings-content.md +473 -0
  74. wxcli/_playbook/docs/reference/meetings-core.md +903 -0
  75. wxcli/_playbook/docs/reference/meetings-infrastructure.md +899 -0
  76. wxcli/_playbook/docs/reference/meetings-settings.md +850 -0
  77. wxcli/_playbook/docs/reference/messaging-bots.md +1091 -0
  78. wxcli/_playbook/docs/reference/messaging-spaces.md +695 -0
  79. wxcli/_playbook/docs/reference/person-call-settings-behavior.md +1639 -0
  80. wxcli/_playbook/docs/reference/person-call-settings-handling.md +1394 -0
  81. wxcli/_playbook/docs/reference/person-call-settings-media.md +1898 -0
  82. wxcli/_playbook/docs/reference/person-call-settings-permissions.md +1329 -0
  83. wxcli/_playbook/docs/reference/provisioning.md +1366 -0
  84. wxcli/_playbook/docs/reference/reporting-analytics.md +1318 -0
  85. wxcli/_playbook/docs/reference/self-service-call-settings.md +1020 -0
  86. wxcli/_playbook/docs/reference/virtual-lines.md +1132 -0
  87. wxcli/_playbook/docs/reference/webhooks-events.md +1444 -0
  88. wxcli/_playbook/docs/reference/wxcadm-xsi-realtime.md +953 -0
  89. wxcli/_version.py +24 -0
  90. wxcli/auth.py +137 -0
  91. wxcli/commands/__init__.py +0 -0
  92. wxcli/commands/_registry.py +181 -0
  93. wxcli/commands/activation_email.py +103 -0
  94. wxcli/commands/admin_recordings.py +585 -0
  95. wxcli/commands/analytics.py +105 -0
  96. wxcli/commands/announcement_playlists.py +219 -0
  97. wxcli/commands/announcements.py +519 -0
  98. wxcli/commands/archive_users.py +36 -0
  99. wxcli/commands/attachment_actions.py +60 -0
  100. wxcli/commands/audit_events.py +83 -0
  101. wxcli/commands/authorizations.py +113 -0
  102. wxcli/commands/auto_attendant.py +642 -0
  103. wxcli/commands/broadworks_billing_reports.py +126 -0
  104. wxcli/commands/broadworks_enterprises.py +160 -0
  105. wxcli/commands/broadworks_subscribers.py +319 -0
  106. wxcli/commands/broadworks_workspaces.py +108 -0
  107. wxcli/commands/call_controls.py +1304 -0
  108. wxcli/commands/call_park.py +494 -0
  109. wxcli/commands/call_pickup.py +229 -0
  110. wxcli/commands/call_queue.py +1878 -0
  111. wxcli/commands/call_recording.py +707 -0
  112. wxcli/commands/call_routing.py +1610 -0
  113. wxcli/commands/call_settings_for_me_phase_5.py +212 -0
  114. wxcli/commands/caller_reputation.py +169 -0
  115. wxcli/commands/calling_service.py +305 -0
  116. wxcli/commands/cc_address_book.py +770 -0
  117. wxcli/commands/cc_agent_greetings.py +242 -0
  118. wxcli/commands/cc_agent_summaries.py +39 -0
  119. wxcli/commands/cc_agent_wellbeing.py +216 -0
  120. wxcli/commands/cc_agents.py +425 -0
  121. wxcli/commands/cc_ai_assistant.py +55 -0
  122. wxcli/commands/cc_ai_feature.py +294 -0
  123. wxcli/commands/cc_audio_files.py +149 -0
  124. wxcli/commands/cc_auto_csat.py +311 -0
  125. wxcli/commands/cc_aux_code.py +458 -0
  126. wxcli/commands/cc_business_hour.py +353 -0
  127. wxcli/commands/cc_call_monitoring.py +228 -0
  128. wxcli/commands/cc_callbacks.py +194 -0
  129. wxcli/commands/cc_campaign.py +212 -0
  130. wxcli/commands/cc_captures.py +39 -0
  131. wxcli/commands/cc_contact_list.py +169 -0
  132. wxcli/commands/cc_contact_number.py +295 -0
  133. wxcli/commands/cc_data_sources.py +235 -0
  134. wxcli/commands/cc_desktop_layout.py +380 -0
  135. wxcli/commands/cc_desktop_profile.py +322 -0
  136. wxcli/commands/cc_dial_number.py +511 -0
  137. wxcli/commands/cc_dial_plan.py +347 -0
  138. wxcli/commands/cc_dnc.py +101 -0
  139. wxcli/commands/cc_entry_point.py +545 -0
  140. wxcli/commands/cc_ewt.py +51 -0
  141. wxcli/commands/cc_flow.py +477 -0
  142. wxcli/commands/cc_global_vars.py +430 -0
  143. wxcli/commands/cc_holiday_list.py +335 -0
  144. wxcli/commands/cc_journey.py +1261 -0
  145. wxcli/commands/cc_legacy_flows.py +49 -0
  146. wxcli/commands/cc_multimedia_profile.py +436 -0
  147. wxcli/commands/cc_notification.py +51 -0
  148. wxcli/commands/cc_outdial_ani.py +604 -0
  149. wxcli/commands/cc_overrides.py +341 -0
  150. wxcli/commands/cc_queue.py +1083 -0
  151. wxcli/commands/cc_queue_stats.py +55 -0
  152. wxcli/commands/cc_realtime.py +51 -0
  153. wxcli/commands/cc_resource_collection.py +312 -0
  154. wxcli/commands/cc_search.py +46 -0
  155. wxcli/commands/cc_site.py +400 -0
  156. wxcli/commands/cc_skill.py +350 -0
  157. wxcli/commands/cc_skill_profile.py +289 -0
  158. wxcli/commands/cc_subscriptions.py +426 -0
  159. wxcli/commands/cc_summaries.py +130 -0
  160. wxcli/commands/cc_tasks.py +844 -0
  161. wxcli/commands/cc_team.py +325 -0
  162. wxcli/commands/cc_user_profiles.py +349 -0
  163. wxcli/commands/cc_users.py +701 -0
  164. wxcli/commands/cc_work_types.py +363 -0
  165. wxcli/commands/cdr.py +89 -0
  166. wxcli/commands/classifications.py +38 -0
  167. wxcli/commands/cleanup.py +1427 -0
  168. wxcli/commands/client_settings.py +72 -0
  169. wxcli/commands/conference.py +328 -0
  170. wxcli/commands/configure.py +72 -0
  171. wxcli/commands/converged_recordings.py +347 -0
  172. wxcli/commands/converged_recordings_export.py +310 -0
  173. wxcli/commands/cq_playlists.py +42 -0
  174. wxcli/commands/cucm.py +2794 -0
  175. wxcli/commands/cucm_config.py +129 -0
  176. wxcli/commands/customer_assist.py +373 -0
  177. wxcli/commands/data_sources.py +227 -0
  178. wxcli/commands/dect_devices.py +787 -0
  179. wxcli/commands/device_configurations.py +77 -0
  180. wxcli/commands/device_dynamic_settings.py +320 -0
  181. wxcli/commands/device_settings.py +1489 -0
  182. wxcli/commands/devices.py +280 -0
  183. wxcli/commands/domains.py +142 -0
  184. wxcli/commands/ecm.py +178 -0
  185. wxcli/commands/emergency_services.py +827 -0
  186. wxcli/commands/events.py +83 -0
  187. wxcli/commands/external_voicemail.py +52 -0
  188. wxcli/commands/groups.py +206 -0
  189. wxcli/commands/guest_management.py +76 -0
  190. wxcli/commands/hds.py +340 -0
  191. wxcli/commands/hot_desk.py +67 -0
  192. wxcli/commands/hot_desking_members.py +118 -0
  193. wxcli/commands/hot_desking_portal.py +124 -0
  194. wxcli/commands/hunt_group.py +577 -0
  195. wxcli/commands/hybrid_clusters.py +71 -0
  196. wxcli/commands/hybrid_connectors.py +67 -0
  197. wxcli/commands/identity_org.py +159 -0
  198. wxcli/commands/init_playbook.py +155 -0
  199. wxcli/commands/licenses.py +106 -0
  200. wxcli/commands/live_monitoring.py +40 -0
  201. wxcli/commands/location_call_handling.py +577 -0
  202. wxcli/commands/location_schedules.py +341 -0
  203. wxcli/commands/location_settings.py +1297 -0
  204. wxcli/commands/location_voicemail.py +494 -0
  205. wxcli/commands/locations.py +336 -0
  206. wxcli/commands/meeting_captions.py +110 -0
  207. wxcli/commands/meeting_chats.py +63 -0
  208. wxcli/commands/meeting_invitees.py +234 -0
  209. wxcli/commands/meeting_messages.py +28 -0
  210. wxcli/commands/meeting_participants.py +278 -0
  211. wxcli/commands/meeting_polls.py +111 -0
  212. wxcli/commands/meeting_preferences.py +515 -0
  213. wxcli/commands/meeting_qa.py +78 -0
  214. wxcli/commands/meeting_qualities.py +43 -0
  215. wxcli/commands/meeting_reports.py +101 -0
  216. wxcli/commands/meeting_session_types.py +105 -0
  217. wxcli/commands/meeting_site.py +57 -0
  218. wxcli/commands/meeting_slido.py +44 -0
  219. wxcli/commands/meeting_summaries.py +92 -0
  220. wxcli/commands/meeting_tracking_codes.py +233 -0
  221. wxcli/commands/meeting_transcripts.py +230 -0
  222. wxcli/commands/meetings.py +1997 -0
  223. wxcli/commands/memberships.py +164 -0
  224. wxcli/commands/messages.py +213 -0
  225. wxcli/commands/mode_management.py +244 -0
  226. wxcli/commands/my_call_settings.py +3577 -0
  227. wxcli/commands/numbers.py +405 -0
  228. wxcli/commands/operating_modes.py +410 -0
  229. wxcli/commands/org_contacts.py +284 -0
  230. wxcli/commands/org_health_cli.py +55 -0
  231. wxcli/commands/org_settings.py +71 -0
  232. wxcli/commands/organizations.py +83 -0
  233. wxcli/commands/paging_group.py +257 -0
  234. wxcli/commands/partner_admins.py +141 -0
  235. wxcli/commands/partner_reports.py +188 -0
  236. wxcli/commands/partner_tags.py +216 -0
  237. wxcli/commands/people.py +279 -0
  238. wxcli/commands/person_call_settings.py +71 -0
  239. wxcli/commands/pstn.py +280 -0
  240. wxcli/commands/recording_report.py +154 -0
  241. wxcli/commands/report_templates.py +38 -0
  242. wxcli/commands/reports.py +144 -0
  243. wxcli/commands/resource_group_memberships.py +160 -0
  244. wxcli/commands/resource_groups.py +67 -0
  245. wxcli/commands/roles.py +63 -0
  246. wxcli/commands/room_tabs.py +160 -0
  247. wxcli/commands/rooms.py +225 -0
  248. wxcli/commands/scim_bulk.py +46 -0
  249. wxcli/commands/scim_groups.py +246 -0
  250. wxcli/commands/scim_schemas.py +82 -0
  251. wxcli/commands/scim_users.py +283 -0
  252. wxcli/commands/security_audit.py +54 -0
  253. wxcli/commands/service_apps.py +51 -0
  254. wxcli/commands/single_number_reach.py +209 -0
  255. wxcli/commands/team_memberships.py +155 -0
  256. wxcli/commands/teams.py +153 -0
  257. wxcli/commands/ucm_profile.py +42 -0
  258. wxcli/commands/update.py +219 -0
  259. wxcli/commands/user_settings.py +5116 -0
  260. wxcli/commands/video_mesh.py +1090 -0
  261. wxcli/commands/virtual_extensions.py +502 -0
  262. wxcli/commands/virtual_line_settings.py +2072 -0
  263. wxcli/commands/webhooks.py +176 -0
  264. wxcli/commands/wholesale_billing_reports.py +147 -0
  265. wxcli/commands/wholesale_provisioning.py +523 -0
  266. wxcli/commands/workspace_locations.py +339 -0
  267. wxcli/commands/workspace_metrics.py +103 -0
  268. wxcli/commands/workspace_personalization.py +70 -0
  269. wxcli/commands/workspace_settings.py +3347 -0
  270. wxcli/commands/workspaces.py +279 -0
  271. wxcli/commands/xapi.py +114 -0
  272. wxcli/config.py +139 -0
  273. wxcli/errors.py +77 -0
  274. wxcli/main.py +210 -0
  275. wxcli/migration/CLAUDE.md +106 -0
  276. wxcli/migration/__init__.py +1 -0
  277. wxcli/migration/advisory/CLAUDE.md +196 -0
  278. wxcli/migration/advisory/__init__.py +46 -0
  279. wxcli/migration/advisory/advisor.py +107 -0
  280. wxcli/migration/advisory/advisory_patterns.py +2552 -0
  281. wxcli/migration/advisory/recommendation_rules.py +835 -0
  282. wxcli/migration/cucm/CLAUDE.md +74 -0
  283. wxcli/migration/cucm/__init__.py +5 -0
  284. wxcli/migration/cucm/connection.py +265 -0
  285. wxcli/migration/cucm/discovery.py +225 -0
  286. wxcli/migration/cucm/extractors/__init__.py +1 -0
  287. wxcli/migration/cucm/extractors/announcements.py +92 -0
  288. wxcli/migration/cucm/extractors/base.py +90 -0
  289. wxcli/migration/cucm/extractors/device_profiles.py +98 -0
  290. wxcli/migration/cucm/extractors/devices.py +193 -0
  291. wxcli/migration/cucm/extractors/e911.py +103 -0
  292. wxcli/migration/cucm/extractors/features.py +309 -0
  293. wxcli/migration/cucm/extractors/helpers.py +73 -0
  294. wxcli/migration/cucm/extractors/informational.py +295 -0
  295. wxcli/migration/cucm/extractors/locations.py +221 -0
  296. wxcli/migration/cucm/extractors/moh.py +100 -0
  297. wxcli/migration/cucm/extractors/remote_destinations.py +96 -0
  298. wxcli/migration/cucm/extractors/routing.py +493 -0
  299. wxcli/migration/cucm/extractors/shared_lines.py +146 -0
  300. wxcli/migration/cucm/extractors/templates.py +229 -0
  301. wxcli/migration/cucm/extractors/tier4.py +173 -0
  302. wxcli/migration/cucm/extractors/users.py +240 -0
  303. wxcli/migration/cucm/extractors/voicemail.py +243 -0
  304. wxcli/migration/cucm/extractors/workspaces.py +88 -0
  305. wxcli/migration/cucm/unity_connection.py +304 -0
  306. wxcli/migration/execute/CLAUDE.md +372 -0
  307. wxcli/migration/execute/__init__.py +303 -0
  308. wxcli/migration/execute/batch.py +277 -0
  309. wxcli/migration/execute/dependency.py +483 -0
  310. wxcli/migration/execute/engine.py +964 -0
  311. wxcli/migration/execute/handlers.py +2232 -0
  312. wxcli/migration/execute/planner.py +1939 -0
  313. wxcli/migration/execute/runtime.py +571 -0
  314. wxcli/migration/export/CLAUDE.md +49 -0
  315. wxcli/migration/export/__init__.py +8 -0
  316. wxcli/migration/export/csv_export.py +126 -0
  317. wxcli/migration/export/deployment_plan.py +479 -0
  318. wxcli/migration/export/json_export.py +60 -0
  319. wxcli/migration/models.py +941 -0
  320. wxcli/migration/phone_models.py +50 -0
  321. wxcli/migration/preflight/CLAUDE.md +52 -0
  322. wxcli/migration/preflight/__init__.py +89 -0
  323. wxcli/migration/preflight/checks.py +911 -0
  324. wxcli/migration/preflight/runner.py +293 -0
  325. wxcli/migration/rate_limiter.py +144 -0
  326. wxcli/migration/report/CLAUDE.md +245 -0
  327. wxcli/migration/report/__init__.py +7 -0
  328. wxcli/migration/report/appendix.py +2437 -0
  329. wxcli/migration/report/assembler.py +183 -0
  330. wxcli/migration/report/charts.py +263 -0
  331. wxcli/migration/report/executive.py +776 -0
  332. wxcli/migration/report/explainer.py +704 -0
  333. wxcli/migration/report/helpers.py +74 -0
  334. wxcli/migration/report/ingest.py +152 -0
  335. wxcli/migration/report/notice_templates.py +192 -0
  336. wxcli/migration/report/score.py +375 -0
  337. wxcli/migration/report/styles.py +1052 -0
  338. wxcli/migration/report/user_diff.py +1052 -0
  339. wxcli/migration/report/user_notice.py +425 -0
  340. wxcli/migration/state.py +139 -0
  341. wxcli/migration/store.py +860 -0
  342. wxcli/migration/transform/CLAUDE.md +107 -0
  343. wxcli/migration/transform/__init__.py +12 -0
  344. wxcli/migration/transform/analysis_pipeline.py +453 -0
  345. wxcli/migration/transform/analyzers/__init__.py +142 -0
  346. wxcli/migration/transform/analyzers/css_permission.py +189 -0
  347. wxcli/migration/transform/analyzers/css_routing.py +335 -0
  348. wxcli/migration/transform/analyzers/device_compatibility.py +122 -0
  349. wxcli/migration/transform/analyzers/dn_ambiguity.py +131 -0
  350. wxcli/migration/transform/analyzers/duplicate_user.py +221 -0
  351. wxcli/migration/transform/analyzers/extension_conflict.py +173 -0
  352. wxcli/migration/transform/analyzers/feature_approximation.py +227 -0
  353. wxcli/migration/transform/analyzers/layout_overflow.py +174 -0
  354. wxcli/migration/transform/analyzers/location_ambiguity.py +184 -0
  355. wxcli/migration/transform/analyzers/missing_data.py +300 -0
  356. wxcli/migration/transform/analyzers/selective_call_handling.py +394 -0
  357. wxcli/migration/transform/analyzers/shared_line.py +170 -0
  358. wxcli/migration/transform/analyzers/voicemail_compatibility.py +267 -0
  359. wxcli/migration/transform/analyzers/workspace_license.py +212 -0
  360. wxcli/migration/transform/cross_reference.py +1136 -0
  361. wxcli/migration/transform/cucm_pattern.py +246 -0
  362. wxcli/migration/transform/decisions.py +301 -0
  363. wxcli/migration/transform/e164.py +145 -0
  364. wxcli/migration/transform/engine.py +256 -0
  365. wxcli/migration/transform/mappers/CLAUDE.md +123 -0
  366. wxcli/migration/transform/mappers/__init__.py +76 -0
  367. wxcli/migration/transform/mappers/announcement_mapper.py +122 -0
  368. wxcli/migration/transform/mappers/base.py +190 -0
  369. wxcli/migration/transform/mappers/button_template_mapper.py +186 -0
  370. wxcli/migration/transform/mappers/call_forwarding_mapper.py +228 -0
  371. wxcli/migration/transform/mappers/call_settings_mapper.py +144 -0
  372. wxcli/migration/transform/mappers/css_mapper.py +868 -0
  373. wxcli/migration/transform/mappers/dect_mapper.py +367 -0
  374. wxcli/migration/transform/mappers/device_layout_mapper.py +289 -0
  375. wxcli/migration/transform/mappers/device_mapper.py +227 -0
  376. wxcli/migration/transform/mappers/device_profile_mapper.py +190 -0
  377. wxcli/migration/transform/mappers/device_settings_mapper.py +464 -0
  378. wxcli/migration/transform/mappers/e911_mapper.py +129 -0
  379. wxcli/migration/transform/mappers/ecbn_mapper.py +263 -0
  380. wxcli/migration/transform/mappers/executive_assistant_mapper.py +156 -0
  381. wxcli/migration/transform/mappers/feature_mapper.py +1179 -0
  382. wxcli/migration/transform/mappers/line_mapper.py +310 -0
  383. wxcli/migration/transform/mappers/location_mapper.py +235 -0
  384. wxcli/migration/transform/mappers/moh_mapper.py +114 -0
  385. wxcli/migration/transform/mappers/monitoring_mapper.py +221 -0
  386. wxcli/migration/transform/mappers/receptionist_mapper.py +245 -0
  387. wxcli/migration/transform/mappers/routing_mapper.py +821 -0
  388. wxcli/migration/transform/mappers/snr_mapper.py +201 -0
  389. wxcli/migration/transform/mappers/softkey_mapper.py +205 -0
  390. wxcli/migration/transform/mappers/user_mapper.py +264 -0
  391. wxcli/migration/transform/mappers/voicemail_group_mapper.py +286 -0
  392. wxcli/migration/transform/mappers/voicemail_mapper.py +514 -0
  393. wxcli/migration/transform/mappers/workspace_mapper.py +464 -0
  394. wxcli/migration/transform/normalizers.py +2008 -0
  395. wxcli/migration/transform/pattern_converter.py +106 -0
  396. wxcli/migration/transform/pipeline.py +271 -0
  397. wxcli/migration/transform/rules.py +255 -0
  398. wxcli/org_health/CLAUDE.md +63 -0
  399. wxcli/org_health/__init__.py +7 -0
  400. wxcli/org_health/analyze.py +93 -0
  401. wxcli/org_health/checks.py +458 -0
  402. wxcli/org_health/collector.py +62 -0
  403. wxcli/org_health/models.py +78 -0
  404. wxcli/org_health/report.py +300 -0
  405. wxcli/output.py +101 -0
  406. wxcli-1.2.0.dist-info/METADATA +505 -0
  407. wxcli-1.2.0.dist-info/RECORD +413 -0
  408. wxcli-1.2.0.dist-info/WHEEL +5 -0
  409. wxcli-1.2.0.dist-info/entry_points.txt +2 -0
  410. wxcli-1.2.0.dist-info/licenses/LICENSE +191 -0
  411. wxcli-1.2.0.dist-info/scm_file_list.json +751 -0
  412. wxcli-1.2.0.dist-info/scm_version.json +8 -0
  413. wxcli-1.2.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,1639 @@
1
+ # Person Call Settings -- Behavior, Devices, Apps & Misc
2
+
3
+ SDK reference for person-level settings that control calling behavior, application/device configuration, shared lines, hoteling, receptionist, number management, preferred answer endpoints, MS Teams integration, mode management, personal assistant, and emergency callback numbers.
4
+
5
+ **Source**: `wxc_sdk.person_settings` submodules
6
+
7
+ ---
8
+
9
+ ## Table of Contents
10
+
11
+ 1. [Common Base Classes](#1-common-base-classes)
12
+ 2. [Calling Behavior](#2-calling-behavior)
13
+ 3. [App Services](#3-app-services)
14
+ 4. [App Shared Line](#4-app-shared-line)
15
+ 5. [Call Bridge](#5-call-bridge)
16
+ 6. [Hoteling](#6-hoteling)
17
+ 7. [Receptionist Client](#7-receptionist-client)
18
+ 8. [Numbers](#8-numbers)
19
+ 9. [Available Numbers](#9-available-numbers)
20
+ 10. [Preferred Answer Endpoint](#10-preferred-answer-endpoint)
21
+ 11. [MS Teams](#11-ms-teams)
22
+ 12. [Mode Management](#12-mode-management)
23
+ 13. [Personal Assistant](#13-personal-assistant)
24
+ 14. [Emergency Callback Number (ECBN)](#14-emergency-callback-number-ecbn)
25
+ 15. [Monitoring](#15-monitoring)
26
+ 16. [Push-to-Talk](#16-push-to-talk)
27
+ 17. [Additional Discovered Endpoints](#17-additional-discovered-endpoints)
28
+
29
+ ---
30
+
31
+ ## 1. Common Base Classes
32
+
33
+ **Source**: `wxc_sdk/person_settings/common.py`
34
+
35
+ ### Two Path Families
36
+
37
+ Person call settings endpoints split across two URL path families:
38
+
39
+ | Family | URL Pattern | Settings |
40
+ |--------|------------|----------|
41
+ | **Classic features** | `/v1/people/{personId}/features/{feature}` | callingBehavior, applications, hoteling, reception, numbers (GET only), monitoring, pushToTalk |
42
+ | **Telephony config** | `/v1/telephony/config/people/{personId}/{feature}` | emergencyCallbackNumber, singleNumberReach, musicOnHold, devices, callCaptions, selective rules, callBridge (via `features/callBridge`), personalAssistant (via `features/personalAssistant`), hotDesking/guest, agent/callerId, dectNetworks, preferredAnswerEndpoint, modeManagement/features, settings/msTeams |
43
+
44
+ **Important endpoint name mismatches** (SDK feature name vs. actual API path):
45
+
46
+ | SDK Feature Name | Actual API Path Segment | Full Path |
47
+ |-----------------|------------------------|-----------|
48
+ | `receptionist` | `reception` | `/people/{id}/features/reception` |
49
+ | `applicationServicesSettings` | `applications` | `/people/{id}/features/applications` |
50
+ | `pushToTalkSettings` | `pushToTalk` | `/people/{id}/features/pushToTalk` |
51
+ | `numbers` | `numbers` (two paths) | GET: `/people/{id}/features/numbers`, PUT: `/telephony/config/people/{id}/numbers` |
52
+
53
+ ### ApiSelector (Enum)
54
+
55
+ Controls which URL path template the API child uses. The same API class can target different entity types.
56
+
57
+ | Value | URL prefix |
58
+ |-------|-----------|
59
+ | `person` | `people/{id}/features/{feature}` |
60
+ | `workspace` | `workspaces/{id}/features/{feature}` |
61
+ | `location` | `telephony/config/locations/{id}/{feature}` |
62
+ | `virtual_line` | `telephony/config/virtualLines/{id}/{feature}` |
63
+
64
+ ### PersonSettingsApiChild
65
+
66
+ Base class for most person-settings APIs. Subclasses set a `feature` class attribute (e.g., `'callingBehavior'`, `'hoteling'`). The base class constructs the endpoint URL via `f_ep(person_id, path=None)` using the selector and feature prefix.
67
+
68
+ Some feature+selector combinations are remapped internally. For example, `('people', 'callBridge')` maps to `telephony/config/people/{id}/features/callBridge`, and `('people', 'emergencyCallbackNumber')` maps to `telephony/config/people/{id}/emergencyCallbackNumber`.
69
+
70
+ ### CLI Examples
71
+
72
+ The `user-settings` command group covers most person-level call settings in this document. Use it as the primary CLI entry point for person behavior and feature configuration.
73
+
74
+ ```bash
75
+ # List all available user-settings commands
76
+ wxcli user-settings --help
77
+
78
+ # Show a person's application services settings (section 3)
79
+ wxcli user-settings show <personId>
80
+
81
+ # Show calling behavior
82
+ wxcli user-settings show-calling-behavior <personId>
83
+
84
+ # Show hoteling settings
85
+ wxcli user-settings show-hoteling <personId>
86
+ ```
87
+
88
+ ---
89
+
90
+ ## 2. Calling Behavior
91
+
92
+ **Source**: `wxc_sdk/person_settings/calling_behavior.py`
93
+ **API class**: `CallingBehaviorApi` (extends `PersonSettingsApiChild`, feature=`'callingBehavior'`)
94
+
95
+ Controls which Webex telephony application handles calls for a person. The organization has a default; individual persons can override it.
96
+
97
+ ### Data Models
98
+
99
+ #### BehaviorType (Enum)
100
+
101
+ | Value | Constant |
102
+ |-------|----------|
103
+ | `NATIVE_WEBEX_TEAMS_CALLING` | `native` -- Webex Teams / Hybrid Calling |
104
+ | `CALL_WITH_APP_REGISTERED_FOR_CISCOTEL` | `cisco_tel` -- Cisco Jabber |
105
+ | `CALL_WITH_APP_REGISTERED_FOR_TEL` | `third_party` -- Third-party app |
106
+ | `CALL_WITH_APP_REGISTERED_FOR_WEBEXCALLTEL` | `webex_calling` -- Webex Calling app |
107
+ | `NATIVE_SIP_CALL_TO_UCM` | `native_sip_call_to_ucm` -- Calling in Webex Teams (Unified CM) |
108
+
109
+ #### CallingBehavior
110
+
111
+ | Field | Type | Description |
112
+ |-------|------|-------------|
113
+ | `behavior_type` | `Optional[BehaviorType]` | Current setting. `None` = use org default. |
114
+ | `effective_behavior_type` | `Optional[BehaviorType]` | Effective value (read-only, reflects org default when `behavior_type` is null). |
115
+ | `profile_id` | `Optional[str]` | UC Manager Profile ID. |
116
+
117
+ ### Methods
118
+
119
+ #### read
120
+
121
+ ```python
122
+ def read(self, person_id: str, org_id: str = None) -> CallingBehavior
123
+ ```
124
+
125
+ Retrieve the calling behavior and UC Manager Profile for a person.
126
+
127
+ - **Scope**: `spark-admin:people_read` (full, user, or read-only admin)
128
+ - **HTTP**: `GET people/{person_id}/features/callingBehavior`
129
+
130
+ #### configure
131
+
132
+ ```python
133
+ def configure(self, person_id: str, settings: CallingBehavior, org_id: str = None)
134
+ ```
135
+
136
+ Update the calling behavior. The `effective_behavior_type` field is excluded from the PUT body (read-only).
137
+
138
+ - **Scope**: `spark-admin:people_write` (full or user admin)
139
+ - **HTTP**: `PUT people/{person_id}/features/callingBehavior`
140
+
141
+ ### Raw HTTP
142
+ <!-- Updated by playbook session 2026-03-18 -->
143
+
144
+ ```python
145
+ from wxc_sdk import WebexSimpleApi
146
+ api = WebexSimpleApi()
147
+ BASE = "https://webexapis.com/v1"
148
+
149
+ # Read calling behavior
150
+ url = f"{BASE}/people/{person_id}/features/callingBehavior"
151
+ result = api.session.rest_get(url)
152
+ # Returns: {"behaviorType": "CALL_WITH_APP_REGISTERED_FOR_WEBEXCALLTEL", "effectiveBehaviorType": "...", "profileId": "..."}
153
+
154
+ # Update calling behavior
155
+ url = f"{BASE}/people/{person_id}/features/callingBehavior"
156
+ body = {
157
+ "behaviorType": "CALL_WITH_APP_REGISTERED_FOR_WEBEXCALLTEL", # or NATIVE_SIP_CALL_TO_UCM, etc.
158
+ "profileId": "<uc-manager-profile-id>" # optional, for UCM behavior
159
+ }
160
+ api.session.rest_put(url, json=body)
161
+ ```
162
+
163
+ > **Note**: The URL path is `people/{person_id}/features/callingBehavior`, NOT `telephony/config/people/{person_id}/callingBehavior`.
164
+
165
+ **CLI**: `wxcli user-call-settings show-calling-behavior <personId>` / `update-calling-behavior <personId>`
166
+
167
+ ---
168
+
169
+ ## 3. App Services
170
+
171
+ **Source**: `wxc_sdk/person_settings/appservices.py`
172
+ **API class**: `AppServicesApi` (extends `ApiChild`, base=`''`)
173
+
174
+ Controls ringing behavior for specific scenarios (Click to Dial, Group Page, Call Park recalled) and which client platforms (browser, desktop, tablet, mobile) can use the Webex Calling application.
175
+
176
+ The `AppServicesApi` also holds a nested `shared_line` attribute (an `AppSharedLineApi` instance) -- see section 4.
177
+
178
+ ### Data Model
179
+
180
+ #### AppServicesSettings
181
+
182
+ | Field | Type | Description |
183
+ |-------|------|-------------|
184
+ | `ring_devices_for_click_to_dial_calls_enabled` | `Optional[bool]` | Ring devices for outbound Click to Dial. |
185
+ | `ring_devices_for_group_page_enabled` | `Optional[bool]` | Ring devices for inbound Group Pages. |
186
+ | `ring_devices_for_call_park_enabled` | `Optional[bool]` | Ring devices for Call Park recalled. |
187
+ | `browser_client_enabled` | `Optional[bool]` | Browser (WebRTC) Webex Calling app enabled. |
188
+ | `browser_client_id` | `Optional[str]` | Device ID of WebRTC client (read-only, present only if enabled). |
189
+ | `desktop_client_enabled` | `Optional[bool]` | Desktop Webex Calling app enabled. |
190
+ | `desktop_client_id` | `Optional[str]` | Device ID of desktop client (read-only). |
191
+ | `tablet_client_enabled` | `Optional[bool]` | Tablet Webex Calling app enabled. |
192
+ | `tablet_client_id` | `Optional[str]` | Device ID of tablet client (read-only). |
193
+ | `mobile_client_enabled` | `Optional[bool]` | Mobile Webex Calling app enabled. |
194
+ | `mobile_client_id` | `Optional[str]` | Device ID of mobile client (read-only). |
195
+ | `available_line_count` | `Optional[int]` | Number of available device licenses (read-only). |
196
+
197
+ The `update()` helper method excludes read-only fields (`*_client_id`, `available_line_count`) from the serialized output.
198
+
199
+ ### Methods
200
+
201
+ #### read
202
+
203
+ ```python
204
+ def read(self, person_id: str, org_id: str = None) -> AppServicesSettings
205
+ ```
206
+
207
+ Retrieve app services settings for a person.
208
+
209
+ - **Scope**: `spark-admin:telephony_config_read` (full, user, read-only, or location admin)
210
+ - **HTTP**: `GET people/{person_id}/features/applications`
211
+
212
+ #### configure
213
+
214
+ ```python
215
+ def configure(self, person_id: str, settings: AppServicesSettings, org_id: str = None)
216
+ ```
217
+
218
+ Update app services settings.
219
+
220
+ - **Scope**: `spark-admin:people_write` (full, user, or location admin)
221
+ - **HTTP**: `PUT people/{person_id}/features/applications`
222
+
223
+ ### Raw HTTP
224
+ <!-- Updated by playbook session 2026-03-18 -->
225
+
226
+ ```python
227
+ from wxc_sdk import WebexSimpleApi
228
+ api = WebexSimpleApi()
229
+ BASE = "https://webexapis.com/v1"
230
+
231
+ # Read application services settings
232
+ url = f"{BASE}/people/{person_id}/features/applications"
233
+ result = api.session.rest_get(url)
234
+ # Returns: {"ringDevicesForClickToDialCallsEnabled": true, "browserClientEnabled": true, "desktopClientEnabled": true, ...}
235
+
236
+ # Update application services settings
237
+ url = f"{BASE}/people/{person_id}/features/applications"
238
+ body = {
239
+ "ringDevicesForClickToDialCallsEnabled": True,
240
+ "ringDevicesForGroupPageEnabled": True,
241
+ "ringDevicesForCallParkEnabled": True,
242
+ "browserClientEnabled": True,
243
+ "desktopClientEnabled": True,
244
+ "tabletClientEnabled": True,
245
+ "mobileClientEnabled": True
246
+ }
247
+ api.session.rest_put(url, json=body)
248
+ ```
249
+
250
+ **CLI**: `wxcli user-call-settings show <personId>` / `update <personId>`
251
+
252
+ ---
253
+
254
+ ## 4. App Shared Line
255
+
256
+ **Source**: `wxc_sdk/person_settings/app_shared_line.py`
257
+ **API class**: `AppSharedLineApi` (extends `ApiChild`, base=`'telephony/config/people'`)
258
+
259
+ Manages shared-line appearance (SLA) members on Webex Calling apps. Like hardware devices, applications support additional shared lines that can be monitored and utilized.
260
+
261
+ Accessed via `AppServicesApi.shared_line` or directly.
262
+
263
+ ### Referenced Data Models (from `wxc_sdk.telephony.devices`)
264
+
265
+ - **`AvailableMember`** -- a person/workspace available for shared-line assignment
266
+ - **`DeviceMember`** -- a member currently assigned to a shared line
267
+ - **`DeviceMembersResponse`** -- response containing primary and secondary members
268
+
269
+ ### Methods
270
+
271
+ #### search_members
272
+
273
+ ```python
274
+ def search_members(self, person_id: str, order: str = None, location: str = None,
275
+ name: str = None, phone_number: str = None, extension: str = None,
276
+ **params) -> Generator[AvailableMember, None, None]
277
+ ```
278
+
279
+ Search for members available for shared-line assignment to a Webex Calling app. Returns a paginated generator.
280
+
281
+ - **Scope**: `spark-admin:telephony_config_read`
282
+ - **HTTP**: `GET telephony/config/people/{person_id}/applications/availableMembers`
283
+
284
+ #### members_count
285
+
286
+ ```python
287
+ def members_count(self, person_id: str, location_id: str = None,
288
+ member_name: str = None, phone_number: str = None,
289
+ extension: str = None, org_id: str = None) -> int
290
+ ```
291
+
292
+ Get the count of members available for shared-line assignment.
293
+
294
+ - **Scope**: `spark-admin:telephony_config_read`
295
+ - **HTTP**: `GET telephony/config/people/{person_id}/applications/availableMembers/count`
296
+
297
+ #### get_members
298
+
299
+ ```python
300
+ def get_members(self, person_id: str) -> DeviceMembersResponse
301
+ ```
302
+
303
+ Get primary and secondary members currently assigned to a shared line on a Webex Calling app.
304
+
305
+ - **Scope**: `spark-admin:telephony_config_read`
306
+ - **HTTP**: `GET telephony/config/people/{person_id}/applications/members`
307
+
308
+ #### update_members
309
+
310
+ ```python
311
+ def update_members(self, person_id: str,
312
+ members: list[Union[DeviceMember, AvailableMember]] = None)
313
+ ```
314
+
315
+ Add or modify shared-line members. Accepts either `DeviceMember` or `AvailableMember` instances (the latter is auto-converted). Port indices are auto-assigned sequentially based on `line_weight`.
316
+
317
+ Fields sent per member: `member_id`, `port`, `primary_owner`, `line_type`, `line_weight`, `line_label`, `allow_call_decline_enabled`.
318
+
319
+ Pass an empty list (or `None`) to clear all members.
320
+
321
+ - **Scope**: `spark-admin:telephony_config_write`
322
+ - **HTTP**: `PUT telephony/config/people/{person_id}/applications/members`
323
+
324
+ ### Raw HTTP
325
+ <!-- Updated by playbook session 2026-03-18 -->
326
+
327
+ ```python
328
+ from wxc_sdk import WebexSimpleApi
329
+ api = WebexSimpleApi()
330
+ BASE = "https://webexapis.com/v1"
331
+
332
+ # Search available members for shared-line assignment
333
+ url = f"{BASE}/telephony/config/people/{person_id}/applications/availableMembers"
334
+ result = api.session.rest_get(url, params={"name": "John"}) # optional filters: location, phoneNumber, extension
335
+
336
+ # Get count of available members
337
+ url = f"{BASE}/telephony/config/people/{person_id}/applications/availableMembers/count"
338
+ result = api.session.rest_get(url)
339
+
340
+ # Get current shared-line members
341
+ url = f"{BASE}/telephony/config/people/{person_id}/applications/members"
342
+ result = api.session.rest_get(url)
343
+
344
+ # Update shared-line members
345
+ url = f"{BASE}/telephony/config/people/{person_id}/applications/members"
346
+ body = {
347
+ "members": [
348
+ {"memberId": "<id>", "port": 1, "primaryOwner": True, "lineType": "SHARED_CALL_APPEARANCE", "lineWeight": 1}
349
+ ]
350
+ }
351
+ api.session.rest_put(url, json=body)
352
+ ```
353
+
354
+ ---
355
+
356
+ ## 5. Call Bridge
357
+
358
+ **Source**: `wxc_sdk/person_settings/callbridge.py`
359
+ **API class**: `CallBridgeApi` (extends `PersonSettingsApiChild`, feature=`'callBridge'`)
360
+
361
+ Controls the UC-One call bridge feature (stutter dial tone when a person is bridged on an active shared line call).
362
+
363
+ **Not supported for Webex for Government (FedRAMP).** See [authentication.md → FedRAMP](authentication.md#webex-for-government-fedramp) for all FedRAMP restrictions.
364
+
365
+ Also used for virtual lines.
366
+
367
+ ### Data Model
368
+
369
+ #### CallBridgeSetting
370
+
371
+ | Field | Type | Description |
372
+ |-------|------|-------------|
373
+ | `warning_tone_enabled` | `bool` | Enable/disable stutter dial tone for all participants when a person is bridged. |
374
+
375
+ ### Methods
376
+
377
+ #### read
378
+
379
+ ```python
380
+ def read(self, entity_id: str, org_id: str = None) -> CallBridgeSetting
381
+ ```
382
+
383
+ Retrieve call bridge settings.
384
+
385
+ - **Scope**: `spark-admin:people_read` (full, user, read-only, or location admin)
386
+ - **HTTP**: `GET telephony/config/people/{entity_id}/features/callBridge`
387
+
388
+ #### configure
389
+
390
+ ```python
391
+ def configure(self, entity_id: str, setting: CallBridgeSetting, org_id: str = None)
392
+ ```
393
+
394
+ Update call bridge settings.
395
+
396
+ - **Scope**: `spark-admin:people_write` (full, user, or location admin)
397
+ - **HTTP**: `PUT telephony/config/people/{entity_id}/features/callBridge`
398
+
399
+ ### Raw HTTP
400
+ <!-- Updated by playbook session 2026-03-18 -->
401
+
402
+ ```python
403
+ from wxc_sdk import WebexSimpleApi
404
+ api = WebexSimpleApi()
405
+ BASE = "https://webexapis.com/v1"
406
+
407
+ # Read call bridge settings
408
+ url = f"{BASE}/telephony/config/people/{person_id}/features/callBridge"
409
+ result = api.session.rest_get(url)
410
+ # Returns: {"warningToneEnabled": true}
411
+
412
+ # Update call bridge settings
413
+ url = f"{BASE}/telephony/config/people/{person_id}/features/callBridge"
414
+ body = {"warningToneEnabled": False}
415
+ api.session.rest_put(url, json=body)
416
+ ```
417
+
418
+ ### CLI Examples
419
+
420
+ ```bash
421
+ # Show call bridge settings for a person
422
+ wxcli user-settings show-call-bridge <personId>
423
+
424
+ # Update call bridge settings
425
+ wxcli user-settings update-call-bridge <personId> --warning-tone-enabled true
426
+ ```
427
+
428
+ ---
429
+
430
+ ## 6. Hoteling
431
+
432
+ **Source**: `wxc_sdk/person_settings/hoteling.py`
433
+ **API class**: `HotelingApi` (extends `PersonSettingsApiChild`, feature=`'hoteling'`)
434
+
435
+ Enables a person's phone profile (number, features, calling plan) to be temporarily loaded onto a shared (host) phone.
436
+
437
+ ### Methods
438
+
439
+ #### read
440
+
441
+ ```python
442
+ def read(self, person_id: str, org_id: str = None) -> bool
443
+ ```
444
+
445
+ Returns a single `bool` indicating whether hoteling is enabled for the person.
446
+
447
+ - **Scope**: `spark-admin:people_read`
448
+ - **HTTP**: `GET people/{person_id}/features/hoteling`
449
+
450
+ #### configure
451
+
452
+ ```python
453
+ def configure(self, person_id: str, enabled: bool, org_id: str = None)
454
+ ```
455
+
456
+ Enable or disable hoteling for a person.
457
+
458
+ - **Scope**: `spark-admin:people_write`
459
+ - **HTTP**: `PUT people/{person_id}/features/hoteling`
460
+ - **Body**: `{"enabled": true/false}`
461
+
462
+ ### Raw HTTP
463
+ <!-- Updated by playbook session 2026-03-18 -->
464
+
465
+ ```python
466
+ from wxc_sdk import WebexSimpleApi
467
+ api = WebexSimpleApi()
468
+ BASE = "https://webexapis.com/v1"
469
+
470
+ # Read hoteling settings
471
+ url = f"{BASE}/people/{person_id}/features/hoteling"
472
+ result = api.session.rest_get(url)
473
+ # Returns: {"enabled": true}
474
+
475
+ # Update hoteling settings
476
+ url = f"{BASE}/people/{person_id}/features/hoteling"
477
+ body = {"enabled": True}
478
+ api.session.rest_put(url, json=body)
479
+ ```
480
+
481
+ **CLI**: `wxcli user-call-settings show-hoteling <personId>` / `update-hoteling <personId>`
482
+
483
+ ### Gotchas
484
+
485
+ - **Person-level hoteling API may be incomplete.** The wxc_sdk source contains a TODO: "this seems to be wrong. For workspace devices methods exist with complete coverage for all hoteling settings." The person-level API only exposes a single boolean toggle (`enabled`), while workspace-level hoteling has richer configuration including host/guest settings and time limits. If you need full hoteling host configuration, use the workspace/device-level APIs instead.
486
+
487
+ ---
488
+
489
+ ## 7. Receptionist Client
490
+
491
+ **Source**: `wxc_sdk/person_settings/receptionist.py`
492
+ **API class**: `ReceptionistApi` (extends `PersonSettingsApiChild`, feature=`'reception'`)
493
+
494
+ Configures a person as a telephone attendant who can screen incoming calls to certain numbers within the organization. The receptionist monitors a list of people and/or workspaces.
495
+
496
+ ### Data Model
497
+
498
+ #### ReceptionistSettings
499
+
500
+ | Field | Type | Description |
501
+ |-------|------|-------------|
502
+ | `enabled` | `Optional[bool]` | Enable/disable the receptionist client feature. Serialized as `receptionEnabled` (alias). |
503
+ | `monitored_members` | `Optional[list[Union[str, MonitoredMember]]]` | People/workspaces to monitor. For updates, can be a list of plain ID strings. |
504
+
505
+ **`MonitoredMember`** is from `wxc_sdk.common`.
506
+
507
+ ### Methods
508
+
509
+ #### read
510
+
511
+ ```python
512
+ def read(self, person_id: str, org_id: str = None) -> ReceptionistSettings
513
+ ```
514
+
515
+ Retrieve receptionist client settings.
516
+
517
+ - **Scope**: `spark-admin:people_read`
518
+ - **HTTP**: `GET people/{person_id}/features/reception`
519
+
520
+ #### configure
521
+
522
+ ```python
523
+ def configure(self, person_id: str, settings: ReceptionistSettings, org_id: str = None)
524
+ ```
525
+
526
+ Update receptionist client settings.
527
+
528
+ **Validation rules enforced in the SDK**:
529
+ - `enabled` must not be `None` (mandatory for updates).
530
+ - If `monitored_members` is set, `enabled` must be `True`.
531
+
532
+ The member list is converted to a list of IDs for the API body (`monitoredMembers`), whether the input contains `str` IDs or `MonitoredMember` objects.
533
+
534
+ - **Scope**: `spark-admin:people_write`
535
+ - **HTTP**: `PUT people/{person_id}/features/reception`
536
+
537
+ ### Raw HTTP
538
+ <!-- Updated by playbook session 2026-03-18 -->
539
+
540
+ ```python
541
+ from wxc_sdk import WebexSimpleApi
542
+ api = WebexSimpleApi()
543
+ BASE = "https://webexapis.com/v1"
544
+
545
+ # Read receptionist client settings
546
+ url = f"{BASE}/people/{person_id}/features/reception"
547
+ result = api.session.rest_get(url)
548
+ # Returns: {"receptionEnabled": true, "monitoredMembers": [{"id": "...", "displayName": "..."}]}
549
+
550
+ # Update receptionist client settings
551
+ url = f"{BASE}/people/{person_id}/features/reception"
552
+ body = {
553
+ "receptionEnabled": True,
554
+ "monitoredMembers": ["<member-id-1>", "<member-id-2>"] # list of person/workspace IDs
555
+ }
556
+ api.session.rest_put(url, json=body)
557
+ ```
558
+
559
+ **CLI**: `wxcli user-call-settings show-reception <personId>` / `update-reception <personId>`
560
+
561
+ ---
562
+
563
+ ## 8. Numbers
564
+
565
+ **Source**: `wxc_sdk/person_settings/numbers.py`
566
+ **API class**: `NumbersApi` (extends `PersonSettingsApiChild`, feature=`'numbers'`)
567
+
568
+ Manages a person's phone numbers, including primary and alternate numbers with distinctive ring patterns.
569
+
570
+ ### Data Models
571
+
572
+ #### PersonPhoneNumber
573
+
574
+ | Field | Type | Description |
575
+ |-------|------|-------------|
576
+ | `primary` | `bool` | Flag indicating if this is the primary number. |
577
+ | `direct_number` | `Optional[str]` | Phone number. |
578
+ | `extension` | `Optional[str]` | Extension. |
579
+ | `routing_prefix` | `Optional[str]` | Routing prefix of the location. |
580
+ | `esn` | `Optional[str]` | Routing prefix + extension. |
581
+ | `ring_pattern` | `Optional[RingPattern]` | Ring pattern (alternate numbers only). |
582
+
583
+ #### PersonNumbers
584
+
585
+ | Field | Type | Description |
586
+ |-------|------|-------------|
587
+ | `distinctive_ring_enabled` | `bool` | Enable distinctive ring patterns for calls from specific numbers. |
588
+ | `phone_numbers` | `list[PersonPhoneNumber]` | List of phone numbers. |
589
+
590
+ #### UpdatePersonPhoneNumber
591
+
592
+ | Field | Type | Description |
593
+ |-------|------|-------------|
594
+ | `primary` | `Literal[False]` | Always `False` (cannot change primary via this API). |
595
+ | `action` | `PatternAction` | `ADD` or `DELETE`. |
596
+ | `external` | `str` | Phone number being assigned/removed. |
597
+ | `extension` | `Optional[str]` | Extension being assigned. |
598
+ | `ring_pattern` | `Optional[RingPattern]` | Ring pattern for the number. |
599
+
600
+ #### UpdatePersonNumbers
601
+
602
+ | Field | Type | Description |
603
+ |-------|------|-------------|
604
+ | `enable_distinctive_ring_pattern` | `Optional[bool]` | Enable/disable distinctive ring. |
605
+ | `phone_numbers` | `list[UpdatePersonPhoneNumber]` | Numbers to add or delete. |
606
+
607
+ ### Methods
608
+
609
+ #### read
610
+
611
+ ```python
612
+ def read(self, person_id: str, prefer_e164_format: bool = None, org_id: str = None) -> PersonNumbers
613
+ ```
614
+
615
+ Get a person's phone numbers including alternate numbers.
616
+
617
+ - **Scope**: `spark-admin:people_read` (full or user admin)
618
+ - **HTTP**: `GET people/{person_id}/features/numbers`
619
+ - **Query param**: `preferE164Format` (optional) -- return numbers in E.164 format.
620
+
621
+ #### update
622
+
623
+ ```python
624
+ def update(self, person_id: str, update: UpdatePersonNumbers, org_id: str = None)
625
+ ```
626
+
627
+ Assign or unassign alternate phone numbers. Numbers must follow E.164 format (except US which also supports National format).
628
+
629
+ - **Scope**: `spark-admin:telephony_config_write` (full admin)
630
+ - **HTTP**: `PUT telephony/config/people/{person_id}/numbers`
631
+
632
+ Note: The update endpoint uses a different URL path (`telephony/config/people/...`) than the read endpoint (`people/.../features/numbers`).
633
+
634
+ ### Raw HTTP
635
+ <!-- Updated by playbook session 2026-03-18 -->
636
+
637
+ ```python
638
+ from wxc_sdk import WebexSimpleApi
639
+ api = WebexSimpleApi()
640
+ BASE = "https://webexapis.com/v1"
641
+
642
+ # Read phone numbers (read path uses people/ prefix)
643
+ url = f"{BASE}/people/{person_id}/features/numbers"
644
+ result = api.session.rest_get(url, params={"preferE164Format": "true"}) # optional
645
+ # Returns: {"distinctiveRingEnabled": true, "phoneNumbers": [{"primary": true, "directNumber": "+1...", "extension": "1234"}]}
646
+
647
+ # Update phone numbers (update path uses telephony/config/people/ prefix -- different from read!)
648
+ url = f"{BASE}/telephony/config/people/{person_id}/numbers"
649
+ body = {
650
+ "enableDistinctiveRingPattern": True,
651
+ "phoneNumbers": [
652
+ {"primary": False, "action": "ADD", "external": "+14085551234", "ringPattern": "NORMAL"}
653
+ ]
654
+ }
655
+ api.session.rest_put(url, json=body)
656
+ ```
657
+
658
+ > **Gotcha**: Read and update use different URL prefixes. Read: `people/{id}/features/numbers`. Update: `telephony/config/people/{id}/numbers`.
659
+
660
+ **CLI**: `wxcli user-call-settings list-numbers <personId>`
661
+
662
+ ### Gotchas
663
+
664
+ - **Read and update use different URL prefixes.** The read endpoint is `GET people/{id}/features/numbers` (under the `people` prefix), but the update endpoint is `PUT telephony/config/people/{id}/numbers` (under the `telephony/config` prefix). Using the wrong prefix will return a 404. This is one of the few person-settings APIs with mismatched read/write paths.
665
+ - **Cannot change primary number via this API.** The `UpdatePersonPhoneNumber` model forces `primary=False`. To change a person's primary number, use the people/provisioning API instead.
666
+ - **Update requires `spark-admin:telephony_config_write` scope**, not `spark-admin:people_write`. This differs from the read scope (`spark-admin:people_read`). Ensure your token has both scopes if doing read-then-update workflows.
667
+
668
+ ---
669
+
670
+ ## 9. Available Numbers
671
+
672
+ **Source**: `wxc_sdk/person_settings/available_numbers.py`
673
+ **API class**: `AvailableNumbersApi` (extends `ApiChild`, base=`'telephony/config'`)
674
+
675
+ Queries for phone numbers available for assignment to a person (or virtual line / workspace, depending on the `ApiSelector` used at construction). Each method targets a different assignment context.
676
+
677
+ ### Data Models
678
+
679
+ #### AvailableNumber
680
+
681
+ | Field | Type | Description |
682
+ |-------|------|-------------|
683
+ | `phone_number` | `Optional[str]` | The phone number. |
684
+ | `extension` | `Optional[str]` | Extension for a PSTN number. |
685
+ | `state` | `Optional[NumberState]` | Phone number state. |
686
+ | `is_main_number` | `Optional[bool]` | Whether it is the location CLID. |
687
+ | `toll_free_number` | `Optional[bool]` | Whether it is toll-free. |
688
+ | `telephony_type` | `Optional[str]` | Telephony type (e.g., `MOBILE_NUMBER`). |
689
+ | `mobile_network` | `Optional[str]` | Mobile network (if mobile number). |
690
+ | `routing_profile` | `Optional[str]` | Routing profile (if mobile number). |
691
+ | `is_service_number` | `Optional[bool]` | High-utilization/concurrency PSTN number (not mobile, not toll-free). |
692
+ | `location` | `Optional[IdAndName]` | Location details. |
693
+ | `owner` | `Optional[NumberOwner]` | Owner details. |
694
+
695
+ #### AvailablePhoneNumberLicenseType (Enum)
696
+
697
+ | Value | Description |
698
+ |-------|-------------|
699
+ | `VAR_STANDARD` | Standard variable license |
700
+ | `VAR_BASIC` | Basic variable license |
701
+ | `Webex Calling Professional` | Professional license |
702
+ | `Webex Calling Standard` | Standard license |
703
+
704
+ ### Method Availability Matrix
705
+
706
+ | Method | People | Virtual Lines | Workspaces |
707
+ |--------|--------|---------------|------------|
708
+ | `primary` | Yes | -- | -- |
709
+ | `secondary` | Yes | -- | Yes |
710
+ | `fax_message` | Yes | Yes | Yes |
711
+ | `call_forward` | Yes | Yes | Yes |
712
+ | `ecbn` | Yes | Yes | Yes |
713
+ | `available` | -- | Yes | Yes |
714
+ | `call_intercept` | Yes | -- | Yes |
715
+
716
+ ### Methods
717
+
718
+ All methods return `Generator[AvailableNumber, None, None]` (paginated).
719
+
720
+ All require scope: `spark-admin:telephony_config_read`.
721
+
722
+ #### primary
723
+
724
+ ```python
725
+ def primary(self, location_id: str = None, phone_number: list[str] = None,
726
+ license_type: AvailablePhoneNumberLicenseType = None,
727
+ org_id: str = None, **params) -> Generator[AvailableNumber, None, None]
728
+ ```
729
+
730
+ List numbers available as a person's primary phone number. Returns standard and mobile numbers from all locations that are unassigned. `license_type` and `location_id` must align with the person's settings for correct assignment.
731
+
732
+ - **HTTP**: `GET telephony/config/people/primary/availableNumbers`
733
+
734
+ #### secondary
735
+
736
+ ```python
737
+ def secondary(self, entity_id: str, phone_number: list[str] = None,
738
+ org_id: str = None, **params) -> Generator[AvailableNumber, None, None]
739
+ ```
740
+
741
+ List standard numbers available as a person's secondary phone number. Numbers are from the entity's location, active or inactive, unassigned.
742
+
743
+ - **HTTP**: `GET telephony/config/people/{entity_id}/secondary/availableNumbers`
744
+
745
+ #### fax_message
746
+
747
+ ```python
748
+ def fax_message(self, entity_id: str, phone_number: list[str] = None,
749
+ org_id: str = None, **params) -> Generator[AvailableNumber, None, None]
750
+ ```
751
+
752
+ List standard numbers available as a FAX message number.
753
+
754
+ - **HTTP**: `GET telephony/config/people/{entity_id}/faxMessage/availableNumbers`
755
+
756
+ #### call_forward
757
+
758
+ ```python
759
+ def call_forward(self, entity_id: str, phone_number: list[str] = None,
760
+ owner_name: str = None, extension: str = None,
761
+ org_id: str = None, **params) -> Generator[AvailableNumber, None, None]
762
+ ```
763
+
764
+ List service and standard numbers available as call forward destinations.
765
+
766
+ - **HTTP**: `GET telephony/config/people/{entity_id}/callForwarding/availableNumbers`
767
+
768
+ #### ecbn
769
+
770
+ ```python
771
+ def ecbn(self, entity_id: str, phone_number: list[str] = None,
772
+ owner_name: str = None, org_id: str = None,
773
+ **params) -> Generator[AvailableNumber, None, None]
774
+ ```
775
+
776
+ List standard numbers available as emergency callback numbers.
777
+
778
+ - **HTTP**: `GET telephony/config/people/{entity_id}/emergencyCallbackNumber/availableNumbers`
779
+
780
+ #### available
781
+
782
+ ```python
783
+ def available(self, location_id: str = None, phone_number: list[str] = None,
784
+ org_id: str = None, **params) -> Generator[AvailableNumber, None, None]
785
+ ```
786
+
787
+ List standard numbers available for assignment (virtual lines and workspaces only -- not people).
788
+
789
+ - **HTTP**: `GET telephony/config/{selector}/availableNumbers`
790
+
791
+ #### call_intercept
792
+
793
+ ```python
794
+ def call_intercept(self, entity_id: str, phone_number: list[str] = None,
795
+ owner_name: str = None, extension: str = None,
796
+ org_id: str = None, **params) -> Generator[AvailableNumber, None, None]
797
+ ```
798
+
799
+ List service and standard numbers available as call intercept numbers.
800
+
801
+ - **HTTP**: `GET telephony/config/people/{entity_id}/callIntercept/availableNumbers`
802
+
803
+ ### Raw HTTP
804
+ <!-- Updated by playbook session 2026-03-18 -->
805
+
806
+ ```python
807
+ from wxc_sdk import WebexSimpleApi
808
+ api = WebexSimpleApi()
809
+ BASE = "https://webexapis.com/v1"
810
+
811
+ # List primary available numbers
812
+ url = f"{BASE}/telephony/config/people/primary/availableNumbers"
813
+ result = api.session.rest_get(url, params={"locationId": "<loc-id>"})
814
+
815
+ # List secondary available numbers
816
+ url = f"{BASE}/telephony/config/people/{person_id}/secondary/availableNumbers"
817
+ result = api.session.rest_get(url)
818
+
819
+ # List available ECBN numbers
820
+ url = f"{BASE}/telephony/config/people/{person_id}/emergencyCallbackNumber/availableNumbers"
821
+ result = api.session.rest_get(url)
822
+
823
+ # List available call forward numbers
824
+ url = f"{BASE}/telephony/config/people/{person_id}/callForwarding/availableNumbers"
825
+ result = api.session.rest_get(url)
826
+
827
+ # List available fax message numbers
828
+ url = f"{BASE}/telephony/config/people/{person_id}/faxMessage/availableNumbers"
829
+ result = api.session.rest_get(url)
830
+
831
+ # List available call intercept numbers
832
+ url = f"{BASE}/telephony/config/people/{person_id}/callIntercept/availableNumbers"
833
+ result = api.session.rest_get(url)
834
+ ```
835
+
836
+ All return paginated arrays of `AvailableNumber` objects.
837
+
838
+ ### CLI Examples
839
+
840
+ ```bash
841
+ # List primary available phone numbers for a person
842
+ wxcli user-settings list-available-numbers-primary --location-id <locationId>
843
+
844
+ # List secondary available phone numbers for a person
845
+ wxcli user-settings list-available-numbers-secondary <personId>
846
+
847
+ # List available ECBN numbers for a person
848
+ wxcli user-settings list-available-numbers-emergency-callback-number <personId>
849
+
850
+ # List available call forward numbers for a person
851
+ wxcli user-settings list-available-numbers-call-forwarding <personId>
852
+
853
+ # List available fax message numbers for a person
854
+ wxcli user-settings list-available-numbers-fax-message <personId>
855
+
856
+ # List available call intercept numbers for a person
857
+ wxcli user-settings list-available-numbers-call-intercept <personId>
858
+ ```
859
+
860
+ ---
861
+
862
+ ## 10. Preferred Answer Endpoint
863
+
864
+ **Source**: `wxc_sdk/person_settings/preferred_answer.py`
865
+ **API class**: `PreferredAnswerApi` (extends `ApiChild`, base=`'telephony/config/people'`)
866
+
867
+ Controls which device or application is the person's preferred answer endpoint. This preferred endpoint can be used by Call Control APIs: `/v1/telephony/calls/dial`, `/v1/telephony/calls/retrieve`, `/v1/telephony/calls/pickup`, `/v1/telephony/calls/barge-in`, `/v1/telephony/calls/answer`.
868
+
869
+ ### Data Models
870
+
871
+ #### PreferredAnswerEndpointType (Enum)
872
+
873
+ | Value | Description |
874
+ |-------|-------------|
875
+ | `APPLICATION` | A software application endpoint |
876
+ | `DEVICE` | A hardware device endpoint |
877
+
878
+ #### PreferredAnswerEndpoint
879
+
880
+ | Field | Type | Description |
881
+ |-------|------|-------------|
882
+ | `id` | `str` | Unique identifier. |
883
+ | `type` | `PreferredAnswerEndpointType` | Device or application. |
884
+ | `name` | `str` | Name (derived from device tag; if `name=<value>` tag is set, that value is used). |
885
+
886
+ #### PreferredAnswerResponse
887
+
888
+ | Field | Type | Description |
889
+ |-------|------|-------------|
890
+ | `preferred_answer_endpoint_id` | `Optional[str]` | Currently preferred endpoint ID (null if none set). |
891
+ | `endpoints` | `list[PreferredAnswerEndpoint]` | All endpoints available for selection. |
892
+
893
+ ### Methods
894
+
895
+ #### read
896
+
897
+ ```python
898
+ def read(self, person_id: str, org_id: str = None) -> PreferredAnswerResponse
899
+ ```
900
+
901
+ Get the preferred answer endpoint and list of available endpoints.
902
+
903
+ - **Scope**: `spark:telephony_config_read` or `spark-admin:telephony_config_read`
904
+ - **HTTP**: `GET telephony/config/people/{person_id}/preferredAnswerEndpoint`
905
+
906
+ #### modify
907
+
908
+ ```python
909
+ def modify(self, person_id: str, preferred_answer_endpoint_id: str, org_id: str = None)
910
+ ```
911
+
912
+ Set or clear the preferred answer endpoint. Pass `None` for `preferred_answer_endpoint_id` to clear.
913
+
914
+ - **Scope**: `spark:telephony_config_write` or `spark-admin:telephony_config_write`
915
+ - **HTTP**: `PUT telephony/config/people/{person_id}/preferredAnswerEndpoint`
916
+ - **Body**: `{"preferredAnswerEndpointId": "<id_or_null>"}`
917
+
918
+ ### Raw HTTP
919
+ <!-- Updated by playbook session 2026-03-18 -->
920
+
921
+ ```python
922
+ from wxc_sdk import WebexSimpleApi
923
+ api = WebexSimpleApi()
924
+ BASE = "https://webexapis.com/v1"
925
+
926
+ # Read preferred answer endpoint
927
+ url = f"{BASE}/telephony/config/people/{person_id}/preferredAnswerEndpoint"
928
+ result = api.session.rest_get(url)
929
+ # Returns: {"preferredAnswerEndpointId": "...", "endpoints": [{"id": "...", "type": "DEVICE", "name": "..."}]}
930
+
931
+ # Set preferred answer endpoint
932
+ url = f"{BASE}/telephony/config/people/{person_id}/preferredAnswerEndpoint"
933
+ body = {"preferredAnswerEndpointId": "<endpoint-id>"} # or None to clear
934
+ api.session.rest_put(url, json=body)
935
+ ```
936
+
937
+ ### CLI Examples
938
+
939
+ ```bash
940
+ # List preferred answer endpoint and all available endpoints for a person
941
+ wxcli user-settings list-preferred-answer-endpoint <personId>
942
+
943
+ # Set a preferred answer endpoint
944
+ wxcli user-settings update-preferred-answer-endpoint <personId> --preferred-answer-endpoint-id <endpointId>
945
+ ```
946
+
947
+ ### Gotchas
948
+
949
+ - **Preferred answer endpoint affects Call Control API behavior.** When set, the `/telephony/calls/dial`, `/telephony/calls/retrieve`, `/telephony/calls/pickup`, `/telephony/calls/barge-in`, and `/telephony/calls/answer` endpoints route to that preferred device/app. If the preferred endpoint is offline or unreachable, call control operations may fail silently or route unexpectedly.
950
+ - **Endpoint names derive from device tags.** The `name` field in `PreferredAnswerEndpoint` comes from the device's `name=<value>` tag. If no tag is set, the name may be a generic device model identifier, making it hard to distinguish between multiple devices of the same type.
951
+
952
+ ---
953
+
954
+ ## 11. MS Teams
955
+
956
+ **Source**: `wxc_sdk/person_settings/msteams.py`
957
+
958
+ Two API classes: one for person-level settings, one for org-level settings.
959
+
960
+ ### Data Models
961
+
962
+ #### SettingsObject
963
+
964
+ | Field | Type | Description |
965
+ |-------|------|-------------|
966
+ | `setting_name` | `Optional[str]` | Name of the setting (e.g., `HIDE_WEBEX_APP`, `PRESENCE_SYNC`). |
967
+ | `level` | `Optional[str]` | Level at which the setting was applied. |
968
+ | `value` | `Optional[bool]` | Current boolean value. |
969
+ | `last_modified` | `Optional[datetime]` | When the setting was last updated. |
970
+
971
+ #### MSTeamsSettings (Person-level)
972
+
973
+ | Field | Type | Description |
974
+ |-------|------|-------------|
975
+ | `person_id` | `Optional[str]` | Person identifier. |
976
+ | `org_id` | `Optional[str]` | Organization identifier. |
977
+ | `settings` | `Optional[list[SettingsObject]]` | Array of settings. |
978
+
979
+ #### OrgMSTeamsSettings (Org-level)
980
+
981
+ | Field | Type | Description |
982
+ |-------|------|-------------|
983
+ | `level` | `Optional[str]` | Level at which settings are applied. |
984
+ | `org_id` | `Optional[str]` | Organization identifier. |
985
+ | `settings` | `Optional[list[SettingsObject]]` | Array of settings. |
986
+
987
+ ### MSTeamsSettingApi (Person-level)
988
+
989
+ **Base**: `ApiChild`, base=`'telephony/config/people'`
990
+
991
+ #### read
992
+
993
+ ```python
994
+ def read(self, person_id: str, org_id: str = None) -> MSTeamsSettings
995
+ ```
996
+
997
+ Retrieve `HIDE_WEBEX_APP` and `PRESENCE_SYNC` settings for a person.
998
+
999
+ - **Scope**: `spark-admin:telephony_config_read` (full or read-only admin)
1000
+ - **HTTP**: `GET telephony/config/people/{person_id}/settings/msTeams`
1001
+
1002
+ #### configure
1003
+
1004
+ ```python
1005
+ def configure(self, person_id: str, setting_name: str, value: bool, org_id: str = None)
1006
+ ```
1007
+
1008
+ Update a single MS Teams setting for a person.
1009
+
1010
+ - **Scope**: `spark-admin:telephony_config_write` (full admin)
1011
+ - **HTTP**: `PUT telephony/config/people/{person_id}/settings/msTeams`
1012
+ - **Body**: `{"settingName": "<name>", "value": true/false}`
1013
+
1014
+ Known setting names: `HIDE_WEBEX_APP`. Set `value` to `null` to delete the setting.
1015
+
1016
+ ### OrgMSTeamsSettingApi (Org-level)
1017
+
1018
+ **Base**: `ApiChild`, base=`'telephony/config/settings/msTeams'`
1019
+ **Not supported for Webex for Government (FedRAMP).** See [authentication.md → FedRAMP](authentication.md#webex-for-government-fedramp) for all FedRAMP restrictions.
1020
+
1021
+ #### read
1022
+
1023
+ ```python
1024
+ def read(self, org_id: str = None) -> OrgMSTeamsSettings
1025
+ ```
1026
+
1027
+ - **Scope**: `spark-admin:telephony_config_read`
1028
+ - **HTTP**: `GET telephony/config/settings/msTeams`
1029
+
1030
+ #### configure
1031
+
1032
+ ```python
1033
+ def configure(self, setting_name: str, value: bool, org_id: str = None)
1034
+ ```
1035
+
1036
+ Update an org-level MS Teams setting. Valid `setting_name` values: `HIDE_WEBEX_APP`, `PRESENCE_SYNC`.
1037
+
1038
+ - **Scope**: `spark-admin:telephony_config_write`
1039
+ - **HTTP**: `PUT telephony/config/settings/msTeams`
1040
+
1041
+ ### Raw HTTP
1042
+ <!-- Updated by playbook session 2026-03-18 -->
1043
+
1044
+ ```python
1045
+ from wxc_sdk import WebexSimpleApi
1046
+ api = WebexSimpleApi()
1047
+ BASE = "https://webexapis.com/v1"
1048
+
1049
+ # Read person-level MS Teams settings
1050
+ url = f"{BASE}/telephony/config/people/{person_id}/settings/msTeams"
1051
+ result = api.session.rest_get(url)
1052
+ # Returns: {"personId": "...", "settings": [{"settingName": "HIDE_WEBEX_APP", "value": true, ...}]}
1053
+
1054
+ # Update person-level MS Teams setting
1055
+ url = f"{BASE}/telephony/config/people/{person_id}/settings/msTeams"
1056
+ body = {"settingName": "HIDE_WEBEX_APP", "value": True}
1057
+ api.session.rest_put(url, json=body)
1058
+
1059
+ # Read org-level MS Teams settings
1060
+ url = f"{BASE}/telephony/config/settings/msTeams"
1061
+ result = api.session.rest_get(url)
1062
+
1063
+ # Update org-level MS Teams setting
1064
+ url = f"{BASE}/telephony/config/settings/msTeams"
1065
+ body = {"settingName": "PRESENCE_SYNC", "value": True}
1066
+ api.session.rest_put(url, json=body)
1067
+ ```
1068
+
1069
+ ### CLI: `client-settings` (Org-Level MS Teams Settings)
1070
+
1071
+ The `client-settings` CLI group manages org-level MS Teams integration settings. These are the same settings documented above for `OrgMSTeamsSettingApi`, exposed as CLI commands.
1072
+
1073
+ | Command | Description |
1074
+ |---------|-------------|
1075
+ | `client-settings list` | Get org MS Teams settings |
1076
+ | `client-settings update` | Update org MS Teams settings |
1077
+
1078
+ ```bash
1079
+ # Get current org-level MS Teams settings
1080
+ wxcli client-settings list
1081
+
1082
+ # Enable presence sync between Webex and MS Teams
1083
+ wxcli client-settings update --setting-name PRESENCE_SYNC --value
1084
+
1085
+ # Hide the Webex app for MS Teams users (org-wide)
1086
+ wxcli client-settings update --setting-name HIDE_WEBEX_APP --value
1087
+
1088
+ # Disable the HIDE_WEBEX_APP setting
1089
+ wxcli client-settings update --setting-name HIDE_WEBEX_APP --no-value
1090
+ ```
1091
+
1092
+ ---
1093
+
1094
+ ## 12. Mode Management
1095
+
1096
+ **Source**: `wxc_sdk/person_settings/mode_management.py`
1097
+ **API class**: `ModeManagementApi` (extends `ApiChild`, base=`'telephony/config/people'`)
1098
+
1099
+ Manages operating mode assignments for a person. Feature identifiers (Auto Attendants, Call Queues, Hunt Groups) with mode-based call forwarding enabled can be assigned to a user. Maximum of 50 features per user.
1100
+
1101
+ ### Data Models
1102
+
1103
+ #### FeatureType (Enum)
1104
+
1105
+ | Value | Description |
1106
+ |-------|-------------|
1107
+ | `AUTO_ATTENDANT` | Auto Attendant |
1108
+ | `CALL_QUEUE` | Call Queue |
1109
+ | `HUNT_GROUP` | Hunt Group |
1110
+
1111
+ #### AvailableFeature
1112
+
1113
+ | Field | Type | Description |
1114
+ |-------|------|-------------|
1115
+ | `id` | `Optional[str]` | Feature identifier. |
1116
+ | `name` | `Optional[str]` | Feature name. |
1117
+ | `type` | `Optional[FeatureType]` | Feature type. |
1118
+ | `phone_number` | `Optional[str]` | Primary phone number. |
1119
+ | `extension` | `Optional[str]` | Extension. |
1120
+
1121
+ #### ExceptionType (Enum)
1122
+
1123
+ Describes how the current operating mode became active as an exception.
1124
+
1125
+ | Value | Description |
1126
+ |-------|-------------|
1127
+ | `MANUAL_SWITCH_BACK` | User manually switched; stays until manual switch back. |
1128
+ | `AUTOMATIC_SWITCH_BACK_EARLY_START` | User started early; auto-switches at end time. |
1129
+ | `AUTOMATIC_SWITCH_BACK_EXTENSION` | User extended current mode; auto-switches at extended end time (up to +12 hrs). |
1130
+ | `AUTOMATIC_SWITCH_BACK_STANDARD` | Normal operation; stays until scheduled end time. |
1131
+
1132
+ #### ModeManagementFeature
1133
+
1134
+ | Field | Type | Description |
1135
+ |-------|------|-------------|
1136
+ | `id` | `Optional[str]` | Feature identifier. |
1137
+ | `name` | `Optional[str]` | Feature name. |
1138
+ | `type` | `Optional[FeatureType]` | Feature type. |
1139
+ | `phone_number` | `Optional[str]` | Primary phone number. |
1140
+ | `extension` | `Optional[str]` | Extension. |
1141
+ | `mode_based_forwarding_enabled` | `Optional[bool]` | Whether mode-based call forwarding is enabled. |
1142
+ | `forward_destination` | `Optional[str]` | Call forwarding destination. |
1143
+ | `current_operating_mode_name` | `Optional[str]` | Name of the current mode. |
1144
+ | `current_operating_mode_id` | `Optional[str]` | ID of the current mode. |
1145
+ | `exception_type` | `Optional[ExceptionType]` | How the current mode was activated. |
1146
+ | `location` | `Optional[IdAndName]` | Location details. |
1147
+
1148
+ ### Methods
1149
+
1150
+ #### available_features
1151
+
1152
+ ```python
1153
+ def available_features(self, person_id: str = None, name: str = None,
1154
+ phone_number: str = None, extension: str = None,
1155
+ order: str = None, org_id: str = None,
1156
+ **params) -> Generator[AvailableFeature, None, None]
1157
+ ```
1158
+
1159
+ List features that can be assigned for mode management. Paginated.
1160
+
1161
+ - **Scope**: `spark-admin:telephony_config_read` (full, read-only, or location admin)
1162
+ - **HTTP**: `GET telephony/config/people/{person_id}/modeManagement/availableFeatures`
1163
+
1164
+ #### assigned_features
1165
+
1166
+ ```python
1167
+ def assigned_features(self, person_id: str = None,
1168
+ org_id: str = None) -> list[ModeManagementFeature]
1169
+ ```
1170
+
1171
+ List features already assigned to a user for mode management. Returns a plain list (not paginated).
1172
+
1173
+ - **Scope**: `spark-admin:telephony_config_read`
1174
+ - **HTTP**: `GET telephony/config/people/{person_id}/modeManagement/features`
1175
+
1176
+ #### assign_features
1177
+
1178
+ ```python
1179
+ def assign_features(self, feature_ids: list[str], person_id: str = None,
1180
+ org_id: str = None)
1181
+ ```
1182
+
1183
+ Assign features for mode management. Max 50 features.
1184
+
1185
+ - **Scope**: `spark-admin:telephony_config_write` (full or location admin)
1186
+ - **HTTP**: `PUT telephony/config/people/{person_id}/modeManagement/features`
1187
+ - **Body**: `{"featureIds": ["id1", "id2", ...]}`
1188
+
1189
+ ### Raw HTTP
1190
+ <!-- Updated by playbook session 2026-03-18 -->
1191
+
1192
+ ```python
1193
+ from wxc_sdk import WebexSimpleApi
1194
+ api = WebexSimpleApi()
1195
+ BASE = "https://webexapis.com/v1"
1196
+
1197
+ # List available features for mode management
1198
+ url = f"{BASE}/telephony/config/people/{person_id}/modeManagement/availableFeatures"
1199
+ result = api.session.rest_get(url)
1200
+
1201
+ # List assigned features
1202
+ url = f"{BASE}/telephony/config/people/{person_id}/modeManagement/features"
1203
+ result = api.session.rest_get(url)
1204
+
1205
+ # Assign features (max 50)
1206
+ url = f"{BASE}/telephony/config/people/{person_id}/modeManagement/features"
1207
+ body = {"featureIds": ["<aa-id>", "<cq-id>", "<hg-id>"]}
1208
+ api.session.rest_put(url, json=body)
1209
+ ```
1210
+
1211
+ ### CLI Examples
1212
+
1213
+ ```bash
1214
+ # List available features for mode management assignment
1215
+ wxcli user-settings list-available-features <personId>
1216
+
1217
+ # List features currently assigned to a user for mode management
1218
+ wxcli user-settings list-mode-management <personId>
1219
+
1220
+ # Assign features to a user for mode management (max 50)
1221
+ wxcli user-settings update-mode-management <personId> --json-body '{"featureIds": ["<aa-id>", "<cq-id>"]}'
1222
+
1223
+ # Additional mode-management commands (org-level mode operations)
1224
+ wxcli mode-management list
1225
+ wxcli mode-management show <featureId>
1226
+ wxcli mode-management switch-mode-for-invoke-1 <featureId>
1227
+ wxcli mode-management switch-to-normal <featureId>
1228
+ ```
1229
+
1230
+ ---
1231
+
1232
+ ## 13. Personal Assistant
1233
+
1234
+ **Source**: `wxc_sdk/person_settings/personal_assistant.py`
1235
+ **API class**: `PersonalAssistantApi` (extends `ApiChild`, base=`''`)
1236
+
1237
+ Manages a user's incoming calls when they are away. Supports presence status, call transfer, and alerting behavior.
1238
+
1239
+ ### Data Models
1240
+
1241
+ #### PersonalAssistantPresence (Enum)
1242
+
1243
+ | Value | Description |
1244
+ |-------|-------------|
1245
+ | `NONE` | Available |
1246
+ | `BUSINESS_TRIP` | Gone for business trip |
1247
+ | `GONE_FOR_THE_DAY` | Gone for the day |
1248
+ | `LUNCH` | Gone for lunch |
1249
+ | `MEETING` | In a meeting |
1250
+ | `OUT_OF_OFFICE` | Out of office |
1251
+ | `TEMPORARILY_OUT` | Temporarily out |
1252
+ | `TRAINING` | In training |
1253
+ | `UNAVAILABLE` | Unavailable |
1254
+ | `VACATION` | On vacation |
1255
+
1256
+ #### PersonalAssistantAlerting (Enum)
1257
+
1258
+ | Value | Description |
1259
+ |-------|-------------|
1260
+ | `ALERT_ME_FIRST` | Ring the recipient first. |
1261
+ | `PLAY_RING_REMINDER` | Reminder ring to the recipient. |
1262
+ | `NONE` | No alert. |
1263
+
1264
+ #### PersonalAssistant
1265
+
1266
+ | Field | Type | Description |
1267
+ |-------|------|-------------|
1268
+ | `enabled` | `Optional[bool]` | Toggle the feature on/off. |
1269
+ | `presence` | `Optional[PersonalAssistantPresence]` | Person's availability status. |
1270
+ | `until_date_time` | `Optional[datetime]` | Date/time until which personal assistant is active. |
1271
+ | `transfer_enabled` | `Optional[bool]` | Allow transfer and forwarding for the call type. |
1272
+ | `transfer_number` | `Optional[str]` | Number to transfer to. |
1273
+ | `alerting` | `Optional[PersonalAssistantAlerting]` | Alert type. |
1274
+ | `alert_me_first_number_of_rings` | `Optional[int]` | Ring count when alerting is `ALERT_ME_FIRST` (range: 2-20). |
1275
+
1276
+ ### Methods
1277
+
1278
+ #### get
1279
+
1280
+ ```python
1281
+ def get(self, person_id: str, org_id: str = None) -> PersonalAssistant
1282
+ ```
1283
+
1284
+ Retrieve personal assistant details.
1285
+
1286
+ - **Scope**: `spark-admin:telephony_config_read` (full, user, or read-only admin)
1287
+ - **HTTP**: `GET telephony/config/people/{person_id}/features/personalAssistant`
1288
+
1289
+ #### update
1290
+
1291
+ ```python
1292
+ def update(self, person_id: str, settings: PersonalAssistant, org_id: str = None)
1293
+ ```
1294
+
1295
+ Update personal assistant settings. Only fields that are set (not unset) are included in the PUT body.
1296
+
1297
+ - **Scope**: `spark-admin:telephony_config_write` (full or user admin)
1298
+ - **HTTP**: `PUT telephony/config/people/{person_id}/features/personalAssistant`
1299
+
1300
+ ### Raw HTTP
1301
+ <!-- Updated by playbook session 2026-03-18 -->
1302
+
1303
+ ```python
1304
+ from wxc_sdk import WebexSimpleApi
1305
+ api = WebexSimpleApi()
1306
+ BASE = "https://webexapis.com/v1"
1307
+
1308
+ # Read personal assistant settings
1309
+ url = f"{BASE}/telephony/config/people/{person_id}/features/personalAssistant"
1310
+ result = api.session.rest_get(url)
1311
+ # Returns: {"enabled": true, "presence": "MEETING", "transferEnabled": true, ...}
1312
+
1313
+ # Update personal assistant settings
1314
+ url = f"{BASE}/telephony/config/people/{person_id}/features/personalAssistant"
1315
+ body = {
1316
+ "enabled": True,
1317
+ "presence": "MEETING",
1318
+ "transferEnabled": True,
1319
+ "transferNumber": "+14085551234",
1320
+ "alerting": "ALERT_ME_FIRST",
1321
+ "alertMeFirstNumberOfRings": 3
1322
+ }
1323
+ api.session.rest_put(url, json=body)
1324
+ ```
1325
+
1326
+ ---
1327
+
1328
+ ## 14. Emergency Callback Number (ECBN)
1329
+
1330
+ **Source**: `wxc_sdk/person_settings/ecbn.py`
1331
+ **API class**: `ECBNApi` (extends `PersonSettingsApiChild`, feature=`'emergencyCallbackNumber'`)
1332
+
1333
+ Manages the Emergency Callback Number for a person (also workspaces and virtual lines). Extension-only users must be set up with accurate ECBNs to make emergency calls.
1334
+
1335
+ ### Data Models
1336
+
1337
+ #### ECBNSelection (Enum -- used for updates)
1338
+
1339
+ | Value | Description |
1340
+ |-------|-------------|
1341
+ | `DIRECT_LINE` | PSAP returns call directly to the member's number. |
1342
+ | `LOCATION_ECBN` | Uses the location's configured ECBN (for users without dedicated numbers). |
1343
+ | `LOCATION_MEMBER_NUMBER` | Uses another user's number at the same location (multi-floor/building scenarios). |
1344
+
1345
+ #### SelectedECBN (Enum -- also used for updates)
1346
+
1347
+ Same values as `ECBNSelection`: `DIRECT_LINE`, `LOCATION_ECBN`, `LOCATION_MEMBER_NUMBER`.
1348
+
1349
+ #### ECBNEffectiveLevel (Enum)
1350
+
1351
+ | Value | Description |
1352
+ |-------|-------------|
1353
+ | `DIRECT_LINE` | Member's own number. |
1354
+ | `LOCATION_ECBN` | Location's configured ECBN. |
1355
+ | `LOCATION_NUMBER` | Location's main number. |
1356
+ | `LOCATION_MEMBER_NUMBER` | Another member's number at the location. |
1357
+ | `NONE` | No selection. |
1358
+
1359
+ #### ECBNQuality (Enum)
1360
+
1361
+ | Value | Description |
1362
+ |-------|-------------|
1363
+ | `RECOMMENDED` | Activated number associated with a user or workspace. |
1364
+ | `NOT_RECOMMENDED` | Activated number associated with a non-user entity (AA, Hunt Group, etc.). |
1365
+ | `INVALID` | Inactive or non-existent number. |
1366
+
1367
+ #### PersonECBNDirectLine
1368
+
1369
+ | Field | Type | Description |
1370
+ |-------|------|-------------|
1371
+ | `phone_number` | `Optional[str]` | Callback phone number. |
1372
+ | `first_name` | `Optional[str]` | User's first name. |
1373
+ | `last_name` | `Optional[str]` | User's last name. |
1374
+ | `effective_level` | `Optional[ECBNEffectiveLevel]` | Source of the emergency CLID. |
1375
+ | `effective_value` | `Optional[str]` | Effective ECBN number (falls back to location main number). |
1376
+ | `quality` | `Optional[ECBNQuality]` | Whether this is a recommended ECBN. |
1377
+
1378
+ #### ECBNLocationMember
1379
+
1380
+ | Field | Type | Description |
1381
+ |-------|------|-------------|
1382
+ | `phone_number` | `Optional[str]` | Callback phone number. |
1383
+ | `first_name` | `Optional[str]` | First name. |
1384
+ | `last_name` | `Optional[str]` | Last name. |
1385
+ | `member_id` | `Optional[str]` | Member ID (user/place/virtual line). |
1386
+ | `member_type` | `Optional[UserType]` | Member type. |
1387
+ | `effective_level` | `Optional[ECBNLocationEffectiveLevel]` | Source of emergency CLID. |
1388
+ | `effective_value` | `Optional[str]` | Effective ECBN number. |
1389
+ | `quality` | `Optional[ECBNQuality]` | Recommendation status. |
1390
+
1391
+ #### ECBNDefault
1392
+
1393
+ | Field | Type | Description |
1394
+ |-------|------|-------------|
1395
+ | `effective_value` | `Optional[str]` | Effective ECBN number. |
1396
+ | `quality` | `Optional[ECBNQuality]` | Recommendation status. |
1397
+
1398
+ #### PersonECBN (Read response)
1399
+
1400
+ | Field | Type | Description |
1401
+ |-------|------|-------------|
1402
+ | `selected` | `Optional[ECBNSelection]` | Current ECBN source selection. |
1403
+ | `direct_line_info` | `Optional[PersonECBNDirectLine]` | Direct line ECBN data. |
1404
+ | `location_ecbn_info` | `Optional[PersonECBNDirectLine]` | Location ECBN data (alias: `locationECBNInfo`). |
1405
+ | `location_member_info` | `Optional[ECBNLocationMember]` | Location member ECBN data. |
1406
+ | `default_info` | `Optional[ECBNDefault]` | Default fallback ECBN data. |
1407
+
1408
+ #### ECBNDependencies
1409
+
1410
+ | Field | Type | Description |
1411
+ |-------|------|-------------|
1412
+ | `is_location_ecbn_default` | `Optional[bool]` | Whether this person is the location's default ECBN. |
1413
+ | `is_self_ecbn_default` | `Optional[bool]` | Whether this person is their own ECBN default. |
1414
+ | `dependent_member_count` | `Optional[int]` | Number of members using this person as their ECBN. |
1415
+
1416
+ ### Methods
1417
+
1418
+ #### read
1419
+
1420
+ ```python
1421
+ def read(self, entity_id: str, org_id: str = None) -> PersonECBN
1422
+ ```
1423
+
1424
+ Retrieve ECBN settings.
1425
+
1426
+ - **Scope**: `spark-admin:telephony_config_read` (full, user, read-only, or location admin)
1427
+ - **HTTP**: `GET telephony/config/people/{entity_id}/emergencyCallbackNumber`
1428
+
1429
+ #### configure
1430
+
1431
+ ```python
1432
+ def configure(self, entity_id: str, selected: SelectedECBN,
1433
+ location_member_id: str = None, org_id: str = None)
1434
+ ```
1435
+
1436
+ Update the ECBN. When `selected` is `LOCATION_MEMBER_NUMBER`, pass `location_member_id` to specify which member's number to use.
1437
+
1438
+ - **Scope**: `spark-admin:telephony_config_write` (full, location, user, or read-only admin)
1439
+ - **HTTP**: `PUT telephony/config/people/{entity_id}/emergencyCallbackNumber`
1440
+ - **Body**: `{"selected": "<value>", "locationMemberId": "<optional>"}`
1441
+
1442
+ #### dependencies
1443
+
1444
+ ```python
1445
+ def dependencies(self, entity_id: str, org_id: str = None) -> ECBNDependencies
1446
+ ```
1447
+
1448
+ Retrieve ECBN dependencies -- whether this entity is used as a default ECBN by its location or by other members.
1449
+
1450
+ - **Scope**: `spark-admin:telephony_config_read` (full, user, read-only, or location admin)
1451
+ - **HTTP**: `GET telephony/config/people/{entity_id}/emergencyCallbackNumber/dependencies`
1452
+
1453
+ ### Raw HTTP
1454
+ <!-- Updated by playbook session 2026-03-18 -->
1455
+
1456
+ ```python
1457
+ from wxc_sdk import WebexSimpleApi
1458
+ api = WebexSimpleApi()
1459
+ BASE = "https://webexapis.com/v1"
1460
+
1461
+ # Read ECBN settings
1462
+ url = f"{BASE}/telephony/config/people/{person_id}/emergencyCallbackNumber"
1463
+ result = api.session.rest_get(url)
1464
+ # Returns: {"selected": "DIRECT_LINE", "directLineInfo": {...}, "locationECBNInfo": {...}, ...}
1465
+
1466
+ # Update ECBN
1467
+ url = f"{BASE}/telephony/config/people/{person_id}/emergencyCallbackNumber"
1468
+ body = {
1469
+ "selected": "LOCATION_MEMBER_NUMBER", # DIRECT_LINE | LOCATION_ECBN | LOCATION_MEMBER_NUMBER
1470
+ "locationMemberId": "<member-id>" # required when selected=LOCATION_MEMBER_NUMBER
1471
+ }
1472
+ api.session.rest_put(url, json=body)
1473
+
1474
+ # Read ECBN dependencies
1475
+ url = f"{BASE}/telephony/config/people/{person_id}/emergencyCallbackNumber/dependencies"
1476
+ result = api.session.rest_get(url)
1477
+ # Returns: {"isLocationEcbnDefault": false, "isSelfEcbnDefault": true, "dependentMemberCount": 3}
1478
+ ```
1479
+
1480
+ ### Gotchas
1481
+
1482
+ - **Two overlapping enums for ECBN selection.** The SDK defines both `ECBNSelection` and `SelectedECBN` with overlapping values (`DIRECT_LINE`, `LOCATION_ECBN`, `LOCATION_MEMBER_NUMBER`). `ECBNSelection` also includes `NONE`, while `SelectedECBN` does not. The `configure()` method uses `SelectedECBN`. When reading, the `selected` field uses `ECBNSelection` which may return `NONE`.
1483
+ - **Read-only admin may have write access.** The docstring for `configure()` lists "read-only administrator" as a valid scope for updating ECBN, which is unusual. Most write operations require full or user admin.
1484
+ - **Check dependencies before changing ECBN.** Use the `dependencies` endpoint before modifying a person's ECBN. If the person is the location's default ECBN or is used by other members (`dependentMemberCount > 0`), changing their number could break emergency callback for multiple users.
1485
+
1486
+ ---
1487
+
1488
+ ## 15. Monitoring
1489
+ <!-- Updated by playbook session 2026-03-18 -->
1490
+
1491
+ Configures which users, call parks, and shared lines a person monitors (busy lamp field / BLF). Present in the CLI but not yet in the wxc_sdk person_settings docs for this file.
1492
+
1493
+ ### Raw HTTP
1494
+
1495
+ ```python
1496
+ from wxc_sdk import WebexSimpleApi
1497
+ api = WebexSimpleApi()
1498
+ BASE = "https://webexapis.com/v1"
1499
+
1500
+ # Read monitoring settings
1501
+ url = f"{BASE}/people/{person_id}/features/monitoring"
1502
+ result = api.session.rest_get(url)
1503
+ # Returns: {"enableCallParkNotification": true, "monitoredMembers": [...]}
1504
+
1505
+ # Update monitoring settings
1506
+ url = f"{BASE}/people/{person_id}/features/monitoring"
1507
+ body = {
1508
+ "enableCallParkNotification": True,
1509
+ "monitoredMembers": [{"id": "<member-id>"}] # use --json-body for full control
1510
+ }
1511
+ api.session.rest_put(url, json=body)
1512
+ ```
1513
+
1514
+ **CLI**: `wxcli user-call-settings show-monitoring <personId>` / `update-monitoring <personId>`
1515
+
1516
+ ### CLI Examples
1517
+
1518
+ ```bash
1519
+ # List monitoring settings (BLF / busy lamp field) for a person
1520
+ wxcli user-settings list-monitoring <personId>
1521
+
1522
+ # Update monitoring settings (use --json-body for member list)
1523
+ wxcli user-settings update-monitoring <personId> --json-body '{"enableCallParkNotification": true, "monitoredMembers": [{"id": "<member-id>"}]}'
1524
+ ```
1525
+
1526
+ ---
1527
+
1528
+ ## 16. Push-to-Talk
1529
+ <!-- Updated by playbook session 2026-03-18 -->
1530
+
1531
+ Configures push-to-talk (intercom) settings for a person, including connection type, access control, and auto-answer. Present in the CLI but not yet in the wxc_sdk person_settings docs for this file.
1532
+
1533
+ ### Raw HTTP
1534
+
1535
+ ```python
1536
+ from wxc_sdk import WebexSimpleApi
1537
+ api = WebexSimpleApi()
1538
+ BASE = "https://webexapis.com/v1"
1539
+
1540
+ # Read push-to-talk settings
1541
+ url = f"{BASE}/people/{person_id}/features/pushToTalk"
1542
+ result = api.session.rest_get(url)
1543
+ # Returns: {"allowAutoAnswer": true, "connectionType": "TWO_WAY", "accessType": "ALLOW_MEMBERS", "members": [...]}
1544
+
1545
+ # Update push-to-talk settings
1546
+ url = f"{BASE}/people/{person_id}/features/pushToTalk"
1547
+ body = {
1548
+ "allowAutoAnswer": True,
1549
+ "connectionType": "TWO_WAY", # ONE_WAY or TWO_WAY
1550
+ "accessType": "ALLOW_MEMBERS", # ALLOW_MEMBERS or block pattern
1551
+ "members": [{"id": "<member-id>"}] # use --json-body for full control
1552
+ }
1553
+ api.session.rest_put(url, json=body)
1554
+ ```
1555
+
1556
+ **CLI**: `wxcli user-call-settings show-push-to-talk <personId>` / `update-push-to-talk <personId>`
1557
+
1558
+ ### CLI Examples
1559
+
1560
+ ```bash
1561
+ # List push-to-talk settings for a person
1562
+ wxcli user-settings list-push-to-talk <personId>
1563
+
1564
+ # Update push-to-talk settings (use --json-body for member list and complex config)
1565
+ wxcli user-settings update-push-to-talk <personId> --json-body '{"allowAutoAnswer": true, "connectionType": "TWO_WAY", "accessType": "ALLOW_MEMBERS", "members": [{"id": "<member-id>"}]}'
1566
+ ```
1567
+
1568
+ ---
1569
+
1570
+ ## 17. Additional Discovered Endpoints
1571
+
1572
+ The following endpoints were discovered via live API probing and are not yet covered by wxc_sdk person_settings modules. They all live under the telephony config path family.
1573
+
1574
+ ### Hot Desking Guest
1575
+
1576
+ ```
1577
+ GET /v1/telephony/config/people/{personId}/features/hotDesking/guest
1578
+ ```
1579
+
1580
+ Returns hot desking guest configuration for a person. Likely controls whether a person can use hot desking as a guest on shared devices.
1581
+
1582
+ ### Agent Caller ID
1583
+
1584
+ ```
1585
+ GET /v1/telephony/config/people/{personId}/agent/callerId
1586
+ ```
1587
+
1588
+ Returns the caller ID settings for a person when acting as a call queue or hunt group agent. Separate from the standard person-level caller ID.
1589
+
1590
+ ### DECT Networks
1591
+
1592
+ ```
1593
+ GET /v1/telephony/config/people/{personId}/dectNetworks
1594
+ ```
1595
+
1596
+ Returns DECT network associations for a person. Lists which DECT networks/handsets are assigned to this user.
1597
+
1598
+ > **Note**: Call Bridge, Personal Assistant, Preferred Answer Endpoint, Mode Management, and MS Teams are also under the telephony config path family but are already documented in sections 5, 13, 10, 12, and 11 respectively.
1599
+
1600
+ ---
1601
+
1602
+ ## Scope Summary
1603
+
1604
+ | API | Read Scope | Write Scope |
1605
+ |-----|-----------|-------------|
1606
+ | Calling Behavior | `spark-admin:people_read` | `spark-admin:people_write` |
1607
+ | App Services | `spark-admin:telephony_config_read` | `spark-admin:people_write` |
1608
+ | App Shared Line | `spark-admin:telephony_config_read` | `spark-admin:telephony_config_write` |
1609
+ | Call Bridge | `spark-admin:people_read` | `spark-admin:people_write` |
1610
+ | Hoteling | `spark-admin:people_read` | `spark-admin:people_write` |
1611
+ | Receptionist | `spark-admin:people_read` | `spark-admin:people_write` |
1612
+ | Numbers (read) | `spark-admin:people_read` | -- |
1613
+ | Numbers (update) | -- | `spark-admin:telephony_config_write` |
1614
+ | Available Numbers | `spark-admin:telephony_config_read` | -- |
1615
+ | Preferred Answer | `spark(-admin):telephony_config_read` | `spark(-admin):telephony_config_write` |
1616
+ | MS Teams | `spark-admin:telephony_config_read` | `spark-admin:telephony_config_write` |
1617
+ | Mode Management | `spark-admin:telephony_config_read` | `spark-admin:telephony_config_write` |
1618
+ | Personal Assistant | `spark-admin:telephony_config_read` | `spark-admin:telephony_config_write` |
1619
+ | ECBN | `spark-admin:telephony_config_read` | `spark-admin:telephony_config_write` |
1620
+ | Monitoring | `spark-admin:people_read` | `spark-admin:people_write` |
1621
+ | Push-to-Talk | `spark-admin:people_read` | `spark-admin:people_write` |
1622
+
1623
+ ---
1624
+
1625
+ ## Gotchas (Cross-Cutting)
1626
+
1627
+ - **Two distinct URL path families for person settings.** See the [Two Path Families](#two-path-families) table in section 1 for the complete mapping. Classic features use `people/{id}/features/{feature}`, while newer/specialized settings use `telephony/config/people/{id}/{feature}`. The Numbers API is the worst case: read uses `people/{id}/features/numbers` but update uses `telephony/config/people/{id}/numbers`. Always check the documented HTTP path for each method rather than assuming a pattern.
1628
+ - **Scope mismatch between read and write.** Several APIs in this doc require different scopes for reading vs. writing. For example, App Services read needs `spark-admin:telephony_config_read` but write needs `spark-admin:people_write`. Numbers read needs `spark-admin:people_read` but update needs `spark-admin:telephony_config_write`. Service apps and integrations should request all four person-settings scopes (`people_read`, `people_write`, `telephony_config_read`, `telephony_config_write`) to avoid unexpected 403 errors.
1629
+ - **`--json-body` required for nested settings.** Monitoring members, push-to-talk members, receptionist monitored members, shared-line members, and mode management feature assignments all require nested JSON arrays. The CLI generator skips deeply nested body fields, so use `--json-body '{...}'` for these operations.
1630
+ - **Person vs. workspace API coverage differs.** Hoteling and call bridge have corresponding workspace-level APIs with richer configuration options. If the person-level API feels limited (e.g., hoteling returns only a boolean), check the workspace/device-level APIs in `docs/reference/devices-workspaces.md`.
1631
+ - **my-settings endpoints require calling-licensed user token.** All `/people/me/*` variants of these endpoints return 404 (error 4008) if the authenticated user lacks a Webex Calling license. Use an admin token with `people/{personId}/` paths instead, or ensure the user token belongs to a calling-licensed user.
1632
+
1633
+ ---
1634
+
1635
+ ## See Also
1636
+
1637
+ - **[Emergency Services Reference](emergency-services.md)** — Organization and location-level ECBN configuration, E911 providers, and emergency location management
1638
+ - **[Devices — Core Reference](devices-core.md)** — Device management, hoteling host configuration, and shared-line appearance settings at the device level
1639
+ - **[self-service-call-settings.md](self-service-call-settings.md)** -- User-level `/people/me/` endpoints for self-service call settings, including 6 user-only settings with no admin path.