@faable/auth-sdk 2.6.13 → 2.6.15

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.
package/spec/openapi.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "info": {
4
4
  "title": "@faablecloud/auth",
5
5
  "description": "Auth Platform made by Faable. Manage Users and Roles",
6
- "version": "2.14.0",
6
+ "version": "2.16.0",
7
7
  "license": {
8
8
  "name": "private",
9
9
  "url": "https://faable.com/docs/platform/privacy-policy"
@@ -378,6 +378,110 @@
378
378
  "additionalProperties": false,
379
379
  "description": "Second-factor policy. Set on the Account as the tenant default; the same object on a Client overrides it **field by field**, so one app can require MFA without changing the rest."
380
380
  },
381
+ "recovery_channels": {
382
+ "type": "object",
383
+ "properties": {
384
+ "enabled": {
385
+ "type": "array",
386
+ "items": {
387
+ "anyOf": [
388
+ {
389
+ "type": "string",
390
+ "enum": [
391
+ "email"
392
+ ]
393
+ },
394
+ {
395
+ "type": "string",
396
+ "enum": [
397
+ "sms"
398
+ ]
399
+ },
400
+ {
401
+ "type": "string",
402
+ "enum": [
403
+ "whatsapp"
404
+ ]
405
+ },
406
+ {
407
+ "type": "string",
408
+ "enum": [
409
+ "factor"
410
+ ]
411
+ }
412
+ ]
413
+ },
414
+ "description": "Channels the tenant has turned on. `email` is always on regardless of this list: it is what every other channel falls back to. A channel listed here is still offered only if the platform can send it, the plan allows it and the user has a verified destination for it."
415
+ },
416
+ "default": {
417
+ "anyOf": [
418
+ {
419
+ "anyOf": [
420
+ {
421
+ "type": "string",
422
+ "enum": [
423
+ "email"
424
+ ]
425
+ },
426
+ {
427
+ "type": "string",
428
+ "enum": [
429
+ "sms"
430
+ ]
431
+ },
432
+ {
433
+ "type": "string",
434
+ "enum": [
435
+ "whatsapp"
436
+ ]
437
+ },
438
+ {
439
+ "type": "string",
440
+ "enum": [
441
+ "factor"
442
+ ]
443
+ }
444
+ ]
445
+ }
446
+ ],
447
+ "description": "The channel used when the user is not asked to choose. Falls back to `email` when it is not available for that user."
448
+ },
449
+ "visible": {
450
+ "type": "array",
451
+ "items": {
452
+ "anyOf": [
453
+ {
454
+ "type": "string",
455
+ "enum": [
456
+ "email"
457
+ ]
458
+ },
459
+ {
460
+ "type": "string",
461
+ "enum": [
462
+ "sms"
463
+ ]
464
+ },
465
+ {
466
+ "type": "string",
467
+ "enum": [
468
+ "whatsapp"
469
+ ]
470
+ },
471
+ {
472
+ "type": "string",
473
+ "enum": [
474
+ "factor"
475
+ ]
476
+ }
477
+ ]
478
+ },
479
+ "description": "Channels the recovery screen offers the user to pick from, after they enter their identifier. Empty (the default) keeps today's behaviour: the default channel is used silently and the response never reveals whether the account exists. A non-empty list shows a picker with masked destinations — which does reveal that the account exists and which channels it has, the same trade-off Google and Microsoft make. A tenant decision."
480
+ }
481
+ },
482
+ "additionalProperties": false,
483
+ "description": "Password-recovery delivery channels. Set on the Account as the tenant default; the same object on a Client overrides it field by field, like `login_methods` and `mfa_policy`."
484
+ },
381
485
  "webauthn_rp_id": {
382
486
  "type": "string",
383
487
  "description": "WebAuthn Relying Party ID for this tenant's passkeys. Defaults to the account domain. Set it to a registrable suffix you own (e.g. `acme.com`) when the login screen is served from more than one host — the RP ID is frozen into every credential at registration, so changing it afterwards invalidates every passkey already enrolled.",
@@ -1431,6 +1535,110 @@
1431
1535
  "additionalProperties": false,
1432
1536
  "description": "Second-factor policy. Set on the Account as the tenant default; the same object on a Client overrides it **field by field**, so one app can require MFA without changing the rest."
1433
1537
  },
1538
+ "recovery_channels": {
1539
+ "type": "object",
1540
+ "properties": {
1541
+ "enabled": {
1542
+ "type": "array",
1543
+ "items": {
1544
+ "anyOf": [
1545
+ {
1546
+ "type": "string",
1547
+ "enum": [
1548
+ "email"
1549
+ ]
1550
+ },
1551
+ {
1552
+ "type": "string",
1553
+ "enum": [
1554
+ "sms"
1555
+ ]
1556
+ },
1557
+ {
1558
+ "type": "string",
1559
+ "enum": [
1560
+ "whatsapp"
1561
+ ]
1562
+ },
1563
+ {
1564
+ "type": "string",
1565
+ "enum": [
1566
+ "factor"
1567
+ ]
1568
+ }
1569
+ ]
1570
+ },
1571
+ "description": "Channels the tenant has turned on. `email` is always on regardless of this list: it is what every other channel falls back to. A channel listed here is still offered only if the platform can send it, the plan allows it and the user has a verified destination for it."
1572
+ },
1573
+ "default": {
1574
+ "anyOf": [
1575
+ {
1576
+ "anyOf": [
1577
+ {
1578
+ "type": "string",
1579
+ "enum": [
1580
+ "email"
1581
+ ]
1582
+ },
1583
+ {
1584
+ "type": "string",
1585
+ "enum": [
1586
+ "sms"
1587
+ ]
1588
+ },
1589
+ {
1590
+ "type": "string",
1591
+ "enum": [
1592
+ "whatsapp"
1593
+ ]
1594
+ },
1595
+ {
1596
+ "type": "string",
1597
+ "enum": [
1598
+ "factor"
1599
+ ]
1600
+ }
1601
+ ]
1602
+ }
1603
+ ],
1604
+ "description": "The channel used when the user is not asked to choose. Falls back to `email` when it is not available for that user."
1605
+ },
1606
+ "visible": {
1607
+ "type": "array",
1608
+ "items": {
1609
+ "anyOf": [
1610
+ {
1611
+ "type": "string",
1612
+ "enum": [
1613
+ "email"
1614
+ ]
1615
+ },
1616
+ {
1617
+ "type": "string",
1618
+ "enum": [
1619
+ "sms"
1620
+ ]
1621
+ },
1622
+ {
1623
+ "type": "string",
1624
+ "enum": [
1625
+ "whatsapp"
1626
+ ]
1627
+ },
1628
+ {
1629
+ "type": "string",
1630
+ "enum": [
1631
+ "factor"
1632
+ ]
1633
+ }
1634
+ ]
1635
+ },
1636
+ "description": "Channels the recovery screen offers the user to pick from, after they enter their identifier. Empty (the default) keeps today's behaviour: the default channel is used silently and the response never reveals whether the account exists. A non-empty list shows a picker with masked destinations — which does reveal that the account exists and which channels it has, the same trade-off Google and Microsoft make. A tenant decision."
1637
+ }
1638
+ },
1639
+ "additionalProperties": false,
1640
+ "description": "Password-recovery delivery channels. Set on the Account as the tenant default; the same object on a Client overrides it field by field, like `login_methods` and `mfa_policy`."
1641
+ },
1434
1642
  "login_flow": {
1435
1643
  "anyOf": [
1436
1644
  {
@@ -1795,92 +2003,203 @@
1795
2003
  }
1796
2004
  ]
1797
2005
  },
1798
- "login_flow": {
1799
- "anyOf": [
1800
- {
1801
- "type": "string"
1802
- },
1803
- {
1804
- "type": "null"
1805
- }
1806
- ]
1807
- },
1808
- "metadata": {
1809
- "type": "object",
1810
- "properties": {},
1811
- "additionalProperties": true,
1812
- "description": "Free-form client metadata. Replaces the whole object — send the full merged value, not a partial delta.",
1813
- "default": {}
1814
- }
1815
- },
1816
- "description": "Partial update for a Client. Only the supplied fields are modified. `client_id` and `client_secret` are not editable through this endpoint to prevent accidental rotation; use a dedicated endpoint when secret rotation is added.",
1817
- "additionalProperties": false
1818
- },
1819
- "ClientUpdateMetadata": {
1820
- "type": "object",
1821
- "properties": {},
1822
- "additionalProperties": true,
1823
- "description": "Free-form client metadata. Replaces the whole object — send the full merged value, not a partial delta.",
1824
- "default": {}
1825
- },
1826
- "User": {
1827
- "type": "object",
1828
- "required": [
1829
- "id",
1830
- "email_verified",
1831
- "phone_verified",
1832
- "logins_count",
1833
- "user_metadata",
1834
- "app_metadata",
1835
- "account",
1836
- "createdAt"
1837
- ],
1838
- "properties": {
1839
- "id": {
1840
- "type": "string",
1841
- "description": "User ID"
1842
- },
1843
- "name": {
1844
- "type": "string",
1845
- "description": "User name",
1846
- "nullable": true
1847
- },
1848
- "username": {
1849
- "type": "string",
1850
- "description": "unique username for this user",
1851
- "nullable": true
1852
- },
1853
- "given_name": {
1854
- "type": "string",
1855
- "description": "Given name",
1856
- "nullable": true
1857
- },
1858
- "family_name": {
1859
- "type": "string",
1860
- "description": "Family name",
1861
- "nullable": true
1862
- },
1863
- "middle_name": {
1864
- "type": "string",
1865
- "description": "Middle name (OIDC §5.1)",
1866
- "nullable": true
1867
- },
1868
- "nickname": {
1869
- "type": "string",
1870
- "description": "Casual name. Distinct from given_name (e.g. \"Mike\" vs \"Michael\"). OIDC §5.1",
1871
- "nullable": true
1872
- },
1873
- "email": {
1874
- "type": "string",
1875
- "description": "User email",
1876
- "nullable": true
1877
- },
1878
- "email_verified": {
1879
- "type": "boolean",
1880
- "description": "true if email is verified",
1881
- "default": false
1882
- },
1883
- "email_verified_method": {
2006
+ "recovery_channels": {
2007
+ "anyOf": [
2008
+ {
2009
+ "type": "object",
2010
+ "properties": {
2011
+ "enabled": {
2012
+ "type": "array",
2013
+ "items": {
2014
+ "anyOf": [
2015
+ {
2016
+ "type": "string",
2017
+ "enum": [
2018
+ "email"
2019
+ ]
2020
+ },
2021
+ {
2022
+ "type": "string",
2023
+ "enum": [
2024
+ "sms"
2025
+ ]
2026
+ },
2027
+ {
2028
+ "type": "string",
2029
+ "enum": [
2030
+ "whatsapp"
2031
+ ]
2032
+ },
2033
+ {
2034
+ "type": "string",
2035
+ "enum": [
2036
+ "factor"
2037
+ ]
2038
+ }
2039
+ ]
2040
+ },
2041
+ "description": "Channels the tenant has turned on. `email` is always on regardless of this list: it is what every other channel falls back to. A channel listed here is still offered only if the platform can send it, the plan allows it and the user has a verified destination for it."
2042
+ },
2043
+ "default": {
2044
+ "anyOf": [
2045
+ {
2046
+ "anyOf": [
2047
+ {
2048
+ "type": "string",
2049
+ "enum": [
2050
+ "email"
2051
+ ]
2052
+ },
2053
+ {
2054
+ "type": "string",
2055
+ "enum": [
2056
+ "sms"
2057
+ ]
2058
+ },
2059
+ {
2060
+ "type": "string",
2061
+ "enum": [
2062
+ "whatsapp"
2063
+ ]
2064
+ },
2065
+ {
2066
+ "type": "string",
2067
+ "enum": [
2068
+ "factor"
2069
+ ]
2070
+ }
2071
+ ]
2072
+ }
2073
+ ],
2074
+ "description": "The channel used when the user is not asked to choose. Falls back to `email` when it is not available for that user."
2075
+ },
2076
+ "visible": {
2077
+ "type": "array",
2078
+ "items": {
2079
+ "anyOf": [
2080
+ {
2081
+ "type": "string",
2082
+ "enum": [
2083
+ "email"
2084
+ ]
2085
+ },
2086
+ {
2087
+ "type": "string",
2088
+ "enum": [
2089
+ "sms"
2090
+ ]
2091
+ },
2092
+ {
2093
+ "type": "string",
2094
+ "enum": [
2095
+ "whatsapp"
2096
+ ]
2097
+ },
2098
+ {
2099
+ "type": "string",
2100
+ "enum": [
2101
+ "factor"
2102
+ ]
2103
+ }
2104
+ ]
2105
+ },
2106
+ "description": "Channels the recovery screen offers the user to pick from, after they enter their identifier. Empty (the default) keeps today's behaviour: the default channel is used silently and the response never reveals whether the account exists. A non-empty list shows a picker with masked destinations — which does reveal that the account exists and which channels it has, the same trade-off Google and Microsoft make. A tenant decision."
2107
+ }
2108
+ },
2109
+ "additionalProperties": false,
2110
+ "description": "Password-recovery delivery channels. Set on the Account as the tenant default; the same object on a Client overrides it field by field, like `login_methods` and `mfa_policy`."
2111
+ },
2112
+ {
2113
+ "type": "null"
2114
+ }
2115
+ ]
2116
+ },
2117
+ "login_flow": {
2118
+ "anyOf": [
2119
+ {
2120
+ "type": "string"
2121
+ },
2122
+ {
2123
+ "type": "null"
2124
+ }
2125
+ ]
2126
+ },
2127
+ "metadata": {
2128
+ "type": "object",
2129
+ "properties": {},
2130
+ "additionalProperties": true,
2131
+ "description": "Free-form client metadata. Replaces the whole object — send the full merged value, not a partial delta.",
2132
+ "default": {}
2133
+ }
2134
+ },
2135
+ "description": "Partial update for a Client. Only the supplied fields are modified. `client_id` and `client_secret` are not editable through this endpoint to prevent accidental rotation; use a dedicated endpoint when secret rotation is added.",
2136
+ "additionalProperties": false
2137
+ },
2138
+ "ClientUpdateMetadata": {
2139
+ "type": "object",
2140
+ "properties": {},
2141
+ "additionalProperties": true,
2142
+ "description": "Free-form client metadata. Replaces the whole object — send the full merged value, not a partial delta.",
2143
+ "default": {}
2144
+ },
2145
+ "User": {
2146
+ "type": "object",
2147
+ "required": [
2148
+ "id",
2149
+ "email_verified",
2150
+ "phone_verified",
2151
+ "logins_count",
2152
+ "user_metadata",
2153
+ "app_metadata",
2154
+ "account",
2155
+ "createdAt"
2156
+ ],
2157
+ "properties": {
2158
+ "id": {
2159
+ "type": "string",
2160
+ "description": "User ID"
2161
+ },
2162
+ "name": {
2163
+ "type": "string",
2164
+ "description": "User name",
2165
+ "nullable": true
2166
+ },
2167
+ "username": {
2168
+ "type": "string",
2169
+ "description": "unique username for this user",
2170
+ "nullable": true
2171
+ },
2172
+ "given_name": {
2173
+ "type": "string",
2174
+ "description": "Given name",
2175
+ "nullable": true
2176
+ },
2177
+ "family_name": {
2178
+ "type": "string",
2179
+ "description": "Family name",
2180
+ "nullable": true
2181
+ },
2182
+ "middle_name": {
2183
+ "type": "string",
2184
+ "description": "Middle name (OIDC §5.1)",
2185
+ "nullable": true
2186
+ },
2187
+ "nickname": {
2188
+ "type": "string",
2189
+ "description": "Casual name. Distinct from given_name (e.g. \"Mike\" vs \"Michael\"). OIDC §5.1",
2190
+ "nullable": true
2191
+ },
2192
+ "email": {
2193
+ "type": "string",
2194
+ "description": "User email",
2195
+ "nullable": true
2196
+ },
2197
+ "email_verified": {
2198
+ "type": "boolean",
2199
+ "description": "true if email is verified",
2200
+ "default": false
2201
+ },
2202
+ "email_verified_method": {
1884
2203
  "anyOf": [
1885
2204
  {
1886
2205
  "type": "string",
@@ -6035,84 +6354,195 @@
6035
6354
  }
6036
6355
  ]
6037
6356
  },
6038
- "webauthn_rp_id": {
6039
- "type": "string",
6040
- "nullable": true
6041
- },
6042
- "login_flow": {
6043
- "type": "string",
6044
- "nullable": true
6045
- }
6046
- },
6047
- "description": "AuthAccountUpdate",
6048
- "additionalProperties": false
6049
- },
6050
- "FactorSummary": {
6051
- "type": "object",
6052
- "required": [
6053
- "id",
6054
- "type"
6055
- ],
6056
- "properties": {
6057
- "id": {
6058
- "type": "string"
6059
- },
6060
- "type": {
6061
- "type": "string"
6062
- },
6063
- "name": {
6064
- "type": "string"
6065
- },
6066
- "confirmed_at": {
6067
- "type": "string"
6068
- },
6069
- "last_used_at": {
6070
- "type": "string"
6071
- },
6072
- "remaining": {
6073
- "type": "integer"
6074
- }
6075
- }
6076
- },
6077
- "OAuthTokenParams": {
6078
- "type": "object",
6079
- "properties": {
6080
- "grant_type": {
6357
+ "recovery_channels": {
6081
6358
  "anyOf": [
6082
6359
  {
6083
- "type": "string",
6084
- "enum": [
6085
- "authorization_code"
6086
- ]
6087
- },
6088
- {
6089
- "type": "string",
6090
- "enum": [
6091
- "client_credentials"
6092
- ]
6093
- },
6094
- {
6095
- "type": "string",
6096
- "enum": [
6097
- "refresh_token"
6098
- ]
6099
- },
6100
- {
6101
- "type": "string",
6102
- "enum": [
6103
- "password"
6104
- ]
6105
- },
6106
- {
6107
- "type": "string",
6108
- "enum": [
6109
- "http://auth0.com/oauth/grant-type/mfa-otp"
6110
- ]
6111
- },
6112
- {
6113
- "type": "string",
6114
- "enum": [
6115
- "http://auth0.com/oauth/grant-type/mfa-recovery-code"
6360
+ "type": "object",
6361
+ "properties": {
6362
+ "enabled": {
6363
+ "type": "array",
6364
+ "items": {
6365
+ "anyOf": [
6366
+ {
6367
+ "type": "string",
6368
+ "enum": [
6369
+ "email"
6370
+ ]
6371
+ },
6372
+ {
6373
+ "type": "string",
6374
+ "enum": [
6375
+ "sms"
6376
+ ]
6377
+ },
6378
+ {
6379
+ "type": "string",
6380
+ "enum": [
6381
+ "whatsapp"
6382
+ ]
6383
+ },
6384
+ {
6385
+ "type": "string",
6386
+ "enum": [
6387
+ "factor"
6388
+ ]
6389
+ }
6390
+ ]
6391
+ },
6392
+ "description": "Channels the tenant has turned on. `email` is always on regardless of this list: it is what every other channel falls back to. A channel listed here is still offered only if the platform can send it, the plan allows it and the user has a verified destination for it."
6393
+ },
6394
+ "default": {
6395
+ "anyOf": [
6396
+ {
6397
+ "anyOf": [
6398
+ {
6399
+ "type": "string",
6400
+ "enum": [
6401
+ "email"
6402
+ ]
6403
+ },
6404
+ {
6405
+ "type": "string",
6406
+ "enum": [
6407
+ "sms"
6408
+ ]
6409
+ },
6410
+ {
6411
+ "type": "string",
6412
+ "enum": [
6413
+ "whatsapp"
6414
+ ]
6415
+ },
6416
+ {
6417
+ "type": "string",
6418
+ "enum": [
6419
+ "factor"
6420
+ ]
6421
+ }
6422
+ ]
6423
+ }
6424
+ ],
6425
+ "description": "The channel used when the user is not asked to choose. Falls back to `email` when it is not available for that user."
6426
+ },
6427
+ "visible": {
6428
+ "type": "array",
6429
+ "items": {
6430
+ "anyOf": [
6431
+ {
6432
+ "type": "string",
6433
+ "enum": [
6434
+ "email"
6435
+ ]
6436
+ },
6437
+ {
6438
+ "type": "string",
6439
+ "enum": [
6440
+ "sms"
6441
+ ]
6442
+ },
6443
+ {
6444
+ "type": "string",
6445
+ "enum": [
6446
+ "whatsapp"
6447
+ ]
6448
+ },
6449
+ {
6450
+ "type": "string",
6451
+ "enum": [
6452
+ "factor"
6453
+ ]
6454
+ }
6455
+ ]
6456
+ },
6457
+ "description": "Channels the recovery screen offers the user to pick from, after they enter their identifier. Empty (the default) keeps today's behaviour: the default channel is used silently and the response never reveals whether the account exists. A non-empty list shows a picker with masked destinations — which does reveal that the account exists and which channels it has, the same trade-off Google and Microsoft make. A tenant decision."
6458
+ }
6459
+ },
6460
+ "additionalProperties": false,
6461
+ "description": "Password-recovery delivery channels. Set on the Account as the tenant default; the same object on a Client overrides it field by field, like `login_methods` and `mfa_policy`."
6462
+ },
6463
+ {
6464
+ "type": "null"
6465
+ }
6466
+ ]
6467
+ },
6468
+ "webauthn_rp_id": {
6469
+ "type": "string",
6470
+ "nullable": true
6471
+ },
6472
+ "login_flow": {
6473
+ "type": "string",
6474
+ "nullable": true
6475
+ }
6476
+ },
6477
+ "description": "AuthAccountUpdate",
6478
+ "additionalProperties": false
6479
+ },
6480
+ "FactorSummary": {
6481
+ "type": "object",
6482
+ "required": [
6483
+ "id",
6484
+ "type"
6485
+ ],
6486
+ "properties": {
6487
+ "id": {
6488
+ "type": "string"
6489
+ },
6490
+ "type": {
6491
+ "type": "string"
6492
+ },
6493
+ "name": {
6494
+ "type": "string"
6495
+ },
6496
+ "confirmed_at": {
6497
+ "type": "string"
6498
+ },
6499
+ "last_used_at": {
6500
+ "type": "string"
6501
+ },
6502
+ "remaining": {
6503
+ "type": "integer"
6504
+ }
6505
+ }
6506
+ },
6507
+ "OAuthTokenParams": {
6508
+ "type": "object",
6509
+ "properties": {
6510
+ "grant_type": {
6511
+ "anyOf": [
6512
+ {
6513
+ "type": "string",
6514
+ "enum": [
6515
+ "authorization_code"
6516
+ ]
6517
+ },
6518
+ {
6519
+ "type": "string",
6520
+ "enum": [
6521
+ "client_credentials"
6522
+ ]
6523
+ },
6524
+ {
6525
+ "type": "string",
6526
+ "enum": [
6527
+ "refresh_token"
6528
+ ]
6529
+ },
6530
+ {
6531
+ "type": "string",
6532
+ "enum": [
6533
+ "password"
6534
+ ]
6535
+ },
6536
+ {
6537
+ "type": "string",
6538
+ "enum": [
6539
+ "http://auth0.com/oauth/grant-type/mfa-otp"
6540
+ ]
6541
+ },
6542
+ {
6543
+ "type": "string",
6544
+ "enum": [
6545
+ "http://auth0.com/oauth/grant-type/mfa-recovery-code"
6116
6546
  ]
6117
6547
  },
6118
6548
  {
@@ -6728,6 +7158,110 @@
6728
7158
  "additionalProperties": false,
6729
7159
  "description": "Second-factor policy. Set on the Account as the tenant default; the same object on a Client overrides it **field by field**, so one app can require MFA without changing the rest."
6730
7160
  },
7161
+ "recovery_channels": {
7162
+ "type": "object",
7163
+ "properties": {
7164
+ "enabled": {
7165
+ "type": "array",
7166
+ "items": {
7167
+ "anyOf": [
7168
+ {
7169
+ "type": "string",
7170
+ "enum": [
7171
+ "email"
7172
+ ]
7173
+ },
7174
+ {
7175
+ "type": "string",
7176
+ "enum": [
7177
+ "sms"
7178
+ ]
7179
+ },
7180
+ {
7181
+ "type": "string",
7182
+ "enum": [
7183
+ "whatsapp"
7184
+ ]
7185
+ },
7186
+ {
7187
+ "type": "string",
7188
+ "enum": [
7189
+ "factor"
7190
+ ]
7191
+ }
7192
+ ]
7193
+ },
7194
+ "description": "Channels the tenant has turned on. `email` is always on regardless of this list: it is what every other channel falls back to. A channel listed here is still offered only if the platform can send it, the plan allows it and the user has a verified destination for it."
7195
+ },
7196
+ "default": {
7197
+ "anyOf": [
7198
+ {
7199
+ "anyOf": [
7200
+ {
7201
+ "type": "string",
7202
+ "enum": [
7203
+ "email"
7204
+ ]
7205
+ },
7206
+ {
7207
+ "type": "string",
7208
+ "enum": [
7209
+ "sms"
7210
+ ]
7211
+ },
7212
+ {
7213
+ "type": "string",
7214
+ "enum": [
7215
+ "whatsapp"
7216
+ ]
7217
+ },
7218
+ {
7219
+ "type": "string",
7220
+ "enum": [
7221
+ "factor"
7222
+ ]
7223
+ }
7224
+ ]
7225
+ }
7226
+ ],
7227
+ "description": "The channel used when the user is not asked to choose. Falls back to `email` when it is not available for that user."
7228
+ },
7229
+ "visible": {
7230
+ "type": "array",
7231
+ "items": {
7232
+ "anyOf": [
7233
+ {
7234
+ "type": "string",
7235
+ "enum": [
7236
+ "email"
7237
+ ]
7238
+ },
7239
+ {
7240
+ "type": "string",
7241
+ "enum": [
7242
+ "sms"
7243
+ ]
7244
+ },
7245
+ {
7246
+ "type": "string",
7247
+ "enum": [
7248
+ "whatsapp"
7249
+ ]
7250
+ },
7251
+ {
7252
+ "type": "string",
7253
+ "enum": [
7254
+ "factor"
7255
+ ]
7256
+ }
7257
+ ]
7258
+ },
7259
+ "description": "Channels the recovery screen offers the user to pick from, after they enter their identifier. Empty (the default) keeps today's behaviour: the default channel is used silently and the response never reveals whether the account exists. A non-empty list shows a picker with masked destinations — which does reveal that the account exists and which channels it has, the same trade-off Google and Microsoft make. A tenant decision."
7260
+ }
7261
+ },
7262
+ "additionalProperties": false,
7263
+ "description": "Password-recovery delivery channels. Set on the Account as the tenant default; the same object on a Client overrides it field by field, like `login_methods` and `mfa_policy`."
7264
+ },
6731
7265
  "webauthn_rp_id": {
6732
7266
  "type": "string",
6733
7267
  "description": "WebAuthn Relying Party ID for this tenant's passkeys. Defaults to the account domain. Set it to a registrable suffix you own (e.g. `acme.com`) when the login screen is served from more than one host — the RP ID is frozen into every credential at registration, so changing it afterwards invalidates every passkey already enrolled.",
@@ -7166,8 +7700,112 @@
7166
7700
  "additionalProperties": false,
7167
7701
  "description": "Second-factor policy. Set on the Account as the tenant default; the same object on a Client overrides it **field by field**, so one app can require MFA without changing the rest."
7168
7702
  },
7169
- "webauthn_rp_id": {
7170
- "type": "string",
7703
+ "recovery_channels": {
7704
+ "type": "object",
7705
+ "properties": {
7706
+ "enabled": {
7707
+ "type": "array",
7708
+ "items": {
7709
+ "anyOf": [
7710
+ {
7711
+ "type": "string",
7712
+ "enum": [
7713
+ "email"
7714
+ ]
7715
+ },
7716
+ {
7717
+ "type": "string",
7718
+ "enum": [
7719
+ "sms"
7720
+ ]
7721
+ },
7722
+ {
7723
+ "type": "string",
7724
+ "enum": [
7725
+ "whatsapp"
7726
+ ]
7727
+ },
7728
+ {
7729
+ "type": "string",
7730
+ "enum": [
7731
+ "factor"
7732
+ ]
7733
+ }
7734
+ ]
7735
+ },
7736
+ "description": "Channels the tenant has turned on. `email` is always on regardless of this list: it is what every other channel falls back to. A channel listed here is still offered only if the platform can send it, the plan allows it and the user has a verified destination for it."
7737
+ },
7738
+ "default": {
7739
+ "anyOf": [
7740
+ {
7741
+ "anyOf": [
7742
+ {
7743
+ "type": "string",
7744
+ "enum": [
7745
+ "email"
7746
+ ]
7747
+ },
7748
+ {
7749
+ "type": "string",
7750
+ "enum": [
7751
+ "sms"
7752
+ ]
7753
+ },
7754
+ {
7755
+ "type": "string",
7756
+ "enum": [
7757
+ "whatsapp"
7758
+ ]
7759
+ },
7760
+ {
7761
+ "type": "string",
7762
+ "enum": [
7763
+ "factor"
7764
+ ]
7765
+ }
7766
+ ]
7767
+ }
7768
+ ],
7769
+ "description": "The channel used when the user is not asked to choose. Falls back to `email` when it is not available for that user."
7770
+ },
7771
+ "visible": {
7772
+ "type": "array",
7773
+ "items": {
7774
+ "anyOf": [
7775
+ {
7776
+ "type": "string",
7777
+ "enum": [
7778
+ "email"
7779
+ ]
7780
+ },
7781
+ {
7782
+ "type": "string",
7783
+ "enum": [
7784
+ "sms"
7785
+ ]
7786
+ },
7787
+ {
7788
+ "type": "string",
7789
+ "enum": [
7790
+ "whatsapp"
7791
+ ]
7792
+ },
7793
+ {
7794
+ "type": "string",
7795
+ "enum": [
7796
+ "factor"
7797
+ ]
7798
+ }
7799
+ ]
7800
+ },
7801
+ "description": "Channels the recovery screen offers the user to pick from, after they enter their identifier. Empty (the default) keeps today's behaviour: the default channel is used silently and the response never reveals whether the account exists. A non-empty list shows a picker with masked destinations — which does reveal that the account exists and which channels it has, the same trade-off Google and Microsoft make. A tenant decision."
7802
+ }
7803
+ },
7804
+ "additionalProperties": false,
7805
+ "description": "Password-recovery delivery channels. Set on the Account as the tenant default; the same object on a Client overrides it field by field, like `login_methods` and `mfa_policy`."
7806
+ },
7807
+ "webauthn_rp_id": {
7808
+ "type": "string",
7171
7809
  "description": "WebAuthn Relying Party ID for this tenant's passkeys. Defaults to the account domain. Set it to a registrable suffix you own (e.g. `acme.com`) when the login screen is served from more than one host — the RP ID is frozen into every credential at registration, so changing it afterwards invalidates every passkey already enrolled.",
7172
7810
  "nullable": true
7173
7811
  },
@@ -7658,6 +8296,110 @@
7658
8296
  "additionalProperties": false,
7659
8297
  "description": "Second-factor policy. Set on the Account as the tenant default; the same object on a Client overrides it **field by field**, so one app can require MFA without changing the rest."
7660
8298
  },
8299
+ "recovery_channels": {
8300
+ "type": "object",
8301
+ "properties": {
8302
+ "enabled": {
8303
+ "type": "array",
8304
+ "items": {
8305
+ "anyOf": [
8306
+ {
8307
+ "type": "string",
8308
+ "enum": [
8309
+ "email"
8310
+ ]
8311
+ },
8312
+ {
8313
+ "type": "string",
8314
+ "enum": [
8315
+ "sms"
8316
+ ]
8317
+ },
8318
+ {
8319
+ "type": "string",
8320
+ "enum": [
8321
+ "whatsapp"
8322
+ ]
8323
+ },
8324
+ {
8325
+ "type": "string",
8326
+ "enum": [
8327
+ "factor"
8328
+ ]
8329
+ }
8330
+ ]
8331
+ },
8332
+ "description": "Channels the tenant has turned on. `email` is always on regardless of this list: it is what every other channel falls back to. A channel listed here is still offered only if the platform can send it, the plan allows it and the user has a verified destination for it."
8333
+ },
8334
+ "default": {
8335
+ "anyOf": [
8336
+ {
8337
+ "anyOf": [
8338
+ {
8339
+ "type": "string",
8340
+ "enum": [
8341
+ "email"
8342
+ ]
8343
+ },
8344
+ {
8345
+ "type": "string",
8346
+ "enum": [
8347
+ "sms"
8348
+ ]
8349
+ },
8350
+ {
8351
+ "type": "string",
8352
+ "enum": [
8353
+ "whatsapp"
8354
+ ]
8355
+ },
8356
+ {
8357
+ "type": "string",
8358
+ "enum": [
8359
+ "factor"
8360
+ ]
8361
+ }
8362
+ ]
8363
+ }
8364
+ ],
8365
+ "description": "The channel used when the user is not asked to choose. Falls back to `email` when it is not available for that user."
8366
+ },
8367
+ "visible": {
8368
+ "type": "array",
8369
+ "items": {
8370
+ "anyOf": [
8371
+ {
8372
+ "type": "string",
8373
+ "enum": [
8374
+ "email"
8375
+ ]
8376
+ },
8377
+ {
8378
+ "type": "string",
8379
+ "enum": [
8380
+ "sms"
8381
+ ]
8382
+ },
8383
+ {
8384
+ "type": "string",
8385
+ "enum": [
8386
+ "whatsapp"
8387
+ ]
8388
+ },
8389
+ {
8390
+ "type": "string",
8391
+ "enum": [
8392
+ "factor"
8393
+ ]
8394
+ }
8395
+ ]
8396
+ },
8397
+ "description": "Channels the recovery screen offers the user to pick from, after they enter their identifier. Empty (the default) keeps today's behaviour: the default channel is used silently and the response never reveals whether the account exists. A non-empty list shows a picker with masked destinations — which does reveal that the account exists and which channels it has, the same trade-off Google and Microsoft make. A tenant decision."
8398
+ }
8399
+ },
8400
+ "additionalProperties": false,
8401
+ "description": "Password-recovery delivery channels. Set on the Account as the tenant default; the same object on a Client overrides it field by field, like `login_methods` and `mfa_policy`."
8402
+ },
7661
8403
  "webauthn_rp_id": {
7662
8404
  "type": "string",
7663
8405
  "description": "WebAuthn Relying Party ID for this tenant's passkeys. Defaults to the account domain. Set it to a registrable suffix you own (e.g. `acme.com`) when the login screen is served from more than one host — the RP ID is frozen into every credential at registration, so changing it afterwards invalidates every passkey already enrolled.",
@@ -7962,92 +8704,203 @@
7962
8704
  }
7963
8705
  ]
7964
8706
  },
7965
- "webauthn_rp_id": {
7966
- "type": "string",
7967
- "nullable": true
7968
- },
7969
- "login_flow": {
7970
- "type": "string",
7971
- "nullable": true
7972
- }
7973
- },
7974
- "description": "AuthAccountUpdate",
7975
- "additionalProperties": false
7976
- }
7977
- }
7978
- },
7979
- "description": "AuthAccountUpdate"
7980
- },
7981
- "parameters": [
7982
- {
7983
- "schema": {
7984
- "type": "string"
7985
- },
7986
- "in": "path",
7987
- "name": "account_id",
7988
- "required": true
7989
- }
7990
- ],
7991
- "security": [
7992
- {
7993
- "bearerAuth": []
7994
- }
7995
- ],
7996
- "responses": {
7997
- "200": {
7998
- "description": "AuthAccount",
7999
- "content": {
8000
- "application/json": {
8001
- "schema": {
8002
- "type": "object",
8003
- "required": [
8004
- "id",
8005
- "name",
8006
- "domain",
8007
- "slug",
8008
- "callback_hostnames",
8009
- "token_signature",
8010
- "token_signing_alg",
8011
- "enabled_locales",
8012
- "notification_settings",
8013
- "createdAt"
8014
- ],
8015
- "properties": {
8016
- "id": {
8017
- "type": "string",
8018
- "description": "AuthAccount ID"
8019
- },
8020
- "name": {
8021
- "type": "string"
8022
- },
8023
- "domain": {
8024
- "type": "string"
8025
- },
8026
- "slug": {
8027
- "type": "string"
8028
- },
8029
- "logo_src": {
8030
- "type": "string",
8031
- "nullable": true
8032
- },
8033
- "icon_src": {
8034
- "type": "string",
8035
- "nullable": true
8036
- },
8037
- "callback_hostnames": {
8038
- "type": "array",
8039
- "items": {
8040
- "type": "string"
8041
- }
8042
- },
8043
- "token_signature": {
8044
- "type": "string",
8045
- "description": "Shared HMAC secret. Used when token_signing_alg is an HS* algorithm; ignored for RS*/ES*/PS*."
8046
- },
8047
- "token_signing_alg": {
8048
- "anyOf": [
8049
- {
8050
- "type": "string",
8707
+ "recovery_channels": {
8708
+ "anyOf": [
8709
+ {
8710
+ "type": "object",
8711
+ "properties": {
8712
+ "enabled": {
8713
+ "type": "array",
8714
+ "items": {
8715
+ "anyOf": [
8716
+ {
8717
+ "type": "string",
8718
+ "enum": [
8719
+ "email"
8720
+ ]
8721
+ },
8722
+ {
8723
+ "type": "string",
8724
+ "enum": [
8725
+ "sms"
8726
+ ]
8727
+ },
8728
+ {
8729
+ "type": "string",
8730
+ "enum": [
8731
+ "whatsapp"
8732
+ ]
8733
+ },
8734
+ {
8735
+ "type": "string",
8736
+ "enum": [
8737
+ "factor"
8738
+ ]
8739
+ }
8740
+ ]
8741
+ },
8742
+ "description": "Channels the tenant has turned on. `email` is always on regardless of this list: it is what every other channel falls back to. A channel listed here is still offered only if the platform can send it, the plan allows it and the user has a verified destination for it."
8743
+ },
8744
+ "default": {
8745
+ "anyOf": [
8746
+ {
8747
+ "anyOf": [
8748
+ {
8749
+ "type": "string",
8750
+ "enum": [
8751
+ "email"
8752
+ ]
8753
+ },
8754
+ {
8755
+ "type": "string",
8756
+ "enum": [
8757
+ "sms"
8758
+ ]
8759
+ },
8760
+ {
8761
+ "type": "string",
8762
+ "enum": [
8763
+ "whatsapp"
8764
+ ]
8765
+ },
8766
+ {
8767
+ "type": "string",
8768
+ "enum": [
8769
+ "factor"
8770
+ ]
8771
+ }
8772
+ ]
8773
+ }
8774
+ ],
8775
+ "description": "The channel used when the user is not asked to choose. Falls back to `email` when it is not available for that user."
8776
+ },
8777
+ "visible": {
8778
+ "type": "array",
8779
+ "items": {
8780
+ "anyOf": [
8781
+ {
8782
+ "type": "string",
8783
+ "enum": [
8784
+ "email"
8785
+ ]
8786
+ },
8787
+ {
8788
+ "type": "string",
8789
+ "enum": [
8790
+ "sms"
8791
+ ]
8792
+ },
8793
+ {
8794
+ "type": "string",
8795
+ "enum": [
8796
+ "whatsapp"
8797
+ ]
8798
+ },
8799
+ {
8800
+ "type": "string",
8801
+ "enum": [
8802
+ "factor"
8803
+ ]
8804
+ }
8805
+ ]
8806
+ },
8807
+ "description": "Channels the recovery screen offers the user to pick from, after they enter their identifier. Empty (the default) keeps today's behaviour: the default channel is used silently and the response never reveals whether the account exists. A non-empty list shows a picker with masked destinations — which does reveal that the account exists and which channels it has, the same trade-off Google and Microsoft make. A tenant decision."
8808
+ }
8809
+ },
8810
+ "additionalProperties": false,
8811
+ "description": "Password-recovery delivery channels. Set on the Account as the tenant default; the same object on a Client overrides it field by field, like `login_methods` and `mfa_policy`."
8812
+ },
8813
+ {
8814
+ "type": "null"
8815
+ }
8816
+ ]
8817
+ },
8818
+ "webauthn_rp_id": {
8819
+ "type": "string",
8820
+ "nullable": true
8821
+ },
8822
+ "login_flow": {
8823
+ "type": "string",
8824
+ "nullable": true
8825
+ }
8826
+ },
8827
+ "description": "AuthAccountUpdate",
8828
+ "additionalProperties": false
8829
+ }
8830
+ }
8831
+ },
8832
+ "description": "AuthAccountUpdate"
8833
+ },
8834
+ "parameters": [
8835
+ {
8836
+ "schema": {
8837
+ "type": "string"
8838
+ },
8839
+ "in": "path",
8840
+ "name": "account_id",
8841
+ "required": true
8842
+ }
8843
+ ],
8844
+ "security": [
8845
+ {
8846
+ "bearerAuth": []
8847
+ }
8848
+ ],
8849
+ "responses": {
8850
+ "200": {
8851
+ "description": "AuthAccount",
8852
+ "content": {
8853
+ "application/json": {
8854
+ "schema": {
8855
+ "type": "object",
8856
+ "required": [
8857
+ "id",
8858
+ "name",
8859
+ "domain",
8860
+ "slug",
8861
+ "callback_hostnames",
8862
+ "token_signature",
8863
+ "token_signing_alg",
8864
+ "enabled_locales",
8865
+ "notification_settings",
8866
+ "createdAt"
8867
+ ],
8868
+ "properties": {
8869
+ "id": {
8870
+ "type": "string",
8871
+ "description": "AuthAccount ID"
8872
+ },
8873
+ "name": {
8874
+ "type": "string"
8875
+ },
8876
+ "domain": {
8877
+ "type": "string"
8878
+ },
8879
+ "slug": {
8880
+ "type": "string"
8881
+ },
8882
+ "logo_src": {
8883
+ "type": "string",
8884
+ "nullable": true
8885
+ },
8886
+ "icon_src": {
8887
+ "type": "string",
8888
+ "nullable": true
8889
+ },
8890
+ "callback_hostnames": {
8891
+ "type": "array",
8892
+ "items": {
8893
+ "type": "string"
8894
+ }
8895
+ },
8896
+ "token_signature": {
8897
+ "type": "string",
8898
+ "description": "Shared HMAC secret. Used when token_signing_alg is an HS* algorithm; ignored for RS*/ES*/PS*."
8899
+ },
8900
+ "token_signing_alg": {
8901
+ "anyOf": [
8902
+ {
8903
+ "type": "string",
8051
8904
  "enum": [
8052
8905
  "RS256"
8053
8906
  ]
@@ -8340,6 +9193,110 @@
8340
9193
  "additionalProperties": false,
8341
9194
  "description": "Second-factor policy. Set on the Account as the tenant default; the same object on a Client overrides it **field by field**, so one app can require MFA without changing the rest."
8342
9195
  },
9196
+ "recovery_channels": {
9197
+ "type": "object",
9198
+ "properties": {
9199
+ "enabled": {
9200
+ "type": "array",
9201
+ "items": {
9202
+ "anyOf": [
9203
+ {
9204
+ "type": "string",
9205
+ "enum": [
9206
+ "email"
9207
+ ]
9208
+ },
9209
+ {
9210
+ "type": "string",
9211
+ "enum": [
9212
+ "sms"
9213
+ ]
9214
+ },
9215
+ {
9216
+ "type": "string",
9217
+ "enum": [
9218
+ "whatsapp"
9219
+ ]
9220
+ },
9221
+ {
9222
+ "type": "string",
9223
+ "enum": [
9224
+ "factor"
9225
+ ]
9226
+ }
9227
+ ]
9228
+ },
9229
+ "description": "Channels the tenant has turned on. `email` is always on regardless of this list: it is what every other channel falls back to. A channel listed here is still offered only if the platform can send it, the plan allows it and the user has a verified destination for it."
9230
+ },
9231
+ "default": {
9232
+ "anyOf": [
9233
+ {
9234
+ "anyOf": [
9235
+ {
9236
+ "type": "string",
9237
+ "enum": [
9238
+ "email"
9239
+ ]
9240
+ },
9241
+ {
9242
+ "type": "string",
9243
+ "enum": [
9244
+ "sms"
9245
+ ]
9246
+ },
9247
+ {
9248
+ "type": "string",
9249
+ "enum": [
9250
+ "whatsapp"
9251
+ ]
9252
+ },
9253
+ {
9254
+ "type": "string",
9255
+ "enum": [
9256
+ "factor"
9257
+ ]
9258
+ }
9259
+ ]
9260
+ }
9261
+ ],
9262
+ "description": "The channel used when the user is not asked to choose. Falls back to `email` when it is not available for that user."
9263
+ },
9264
+ "visible": {
9265
+ "type": "array",
9266
+ "items": {
9267
+ "anyOf": [
9268
+ {
9269
+ "type": "string",
9270
+ "enum": [
9271
+ "email"
9272
+ ]
9273
+ },
9274
+ {
9275
+ "type": "string",
9276
+ "enum": [
9277
+ "sms"
9278
+ ]
9279
+ },
9280
+ {
9281
+ "type": "string",
9282
+ "enum": [
9283
+ "whatsapp"
9284
+ ]
9285
+ },
9286
+ {
9287
+ "type": "string",
9288
+ "enum": [
9289
+ "factor"
9290
+ ]
9291
+ }
9292
+ ]
9293
+ },
9294
+ "description": "Channels the recovery screen offers the user to pick from, after they enter their identifier. Empty (the default) keeps today's behaviour: the default channel is used silently and the response never reveals whether the account exists. A non-empty list shows a picker with masked destinations — which does reveal that the account exists and which channels it has, the same trade-off Google and Microsoft make. A tenant decision."
9295
+ }
9296
+ },
9297
+ "additionalProperties": false,
9298
+ "description": "Password-recovery delivery channels. Set on the Account as the tenant default; the same object on a Client overrides it field by field, like `login_methods` and `mfa_policy`."
9299
+ },
8343
9300
  "webauthn_rp_id": {
8344
9301
  "type": "string",
8345
9302
  "description": "WebAuthn Relying Party ID for this tenant's passkeys. Defaults to the account domain. Set it to a registrable suffix you own (e.g. `acme.com`) when the login screen is served from more than one host — the RP ID is frozen into every credential at registration, so changing it afterwards invalidates every passkey already enrolled.",
@@ -8701,55 +9658,159 @@
8701
9658
  {
8702
9659
  "type": "string",
8703
9660
  "enum": [
8704
- "off"
9661
+ "off"
9662
+ ]
9663
+ },
9664
+ {
9665
+ "type": "string",
9666
+ "enum": [
9667
+ "optional"
9668
+ ]
9669
+ },
9670
+ {
9671
+ "type": "string",
9672
+ "enum": [
9673
+ "required"
9674
+ ]
9675
+ }
9676
+ ]
9677
+ }
9678
+ ],
9679
+ "description": "`off` (default) never challenges. `optional` challenges a user who has enrolled a factor, and lets everyone else in. `required` challenges everyone and sends users with no factor through enrolment during login — it never locks anyone out in place."
9680
+ },
9681
+ "allowed_factors": {
9682
+ "type": "array",
9683
+ "items": {
9684
+ "anyOf": [
9685
+ {
9686
+ "type": "string",
9687
+ "enum": [
9688
+ "totp"
9689
+ ]
9690
+ },
9691
+ {
9692
+ "type": "string",
9693
+ "enum": [
9694
+ "webauthn"
9695
+ ]
9696
+ }
9697
+ ]
9698
+ },
9699
+ "description": "Which kinds of second factor satisfy the policy. Empty or unset means all of them. A user whose only factor is of a kind not listed here is treated as having none."
9700
+ },
9701
+ "remember_device_days": {
9702
+ "type": "integer",
9703
+ "minimum": 0,
9704
+ "maximum": 365,
9705
+ "description": "How long a browser that already passed a challenge may skip the next one. 0 (default) challenges every time."
9706
+ }
9707
+ },
9708
+ "additionalProperties": false,
9709
+ "description": "Second-factor policy. Set on the Account as the tenant default; the same object on a Client overrides it **field by field**, so one app can require MFA without changing the rest."
9710
+ },
9711
+ "recovery_channels": {
9712
+ "type": "object",
9713
+ "properties": {
9714
+ "enabled": {
9715
+ "type": "array",
9716
+ "items": {
9717
+ "anyOf": [
9718
+ {
9719
+ "type": "string",
9720
+ "enum": [
9721
+ "email"
9722
+ ]
9723
+ },
9724
+ {
9725
+ "type": "string",
9726
+ "enum": [
9727
+ "sms"
9728
+ ]
9729
+ },
9730
+ {
9731
+ "type": "string",
9732
+ "enum": [
9733
+ "whatsapp"
9734
+ ]
9735
+ },
9736
+ {
9737
+ "type": "string",
9738
+ "enum": [
9739
+ "factor"
9740
+ ]
9741
+ }
9742
+ ]
9743
+ },
9744
+ "description": "Channels the tenant has turned on. `email` is always on regardless of this list: it is what every other channel falls back to. A channel listed here is still offered only if the platform can send it, the plan allows it and the user has a verified destination for it."
9745
+ },
9746
+ "default": {
9747
+ "anyOf": [
9748
+ {
9749
+ "anyOf": [
9750
+ {
9751
+ "type": "string",
9752
+ "enum": [
9753
+ "email"
8705
9754
  ]
8706
9755
  },
8707
9756
  {
8708
9757
  "type": "string",
8709
9758
  "enum": [
8710
- "optional"
9759
+ "sms"
8711
9760
  ]
8712
9761
  },
8713
9762
  {
8714
9763
  "type": "string",
8715
9764
  "enum": [
8716
- "required"
9765
+ "whatsapp"
9766
+ ]
9767
+ },
9768
+ {
9769
+ "type": "string",
9770
+ "enum": [
9771
+ "factor"
8717
9772
  ]
8718
9773
  }
8719
9774
  ]
8720
9775
  }
8721
9776
  ],
8722
- "description": "`off` (default) never challenges. `optional` challenges a user who has enrolled a factor, and lets everyone else in. `required` challenges everyone and sends users with no factor through enrolment during login — it never locks anyone out in place."
9777
+ "description": "The channel used when the user is not asked to choose. Falls back to `email` when it is not available for that user."
8723
9778
  },
8724
- "allowed_factors": {
9779
+ "visible": {
8725
9780
  "type": "array",
8726
9781
  "items": {
8727
9782
  "anyOf": [
8728
9783
  {
8729
9784
  "type": "string",
8730
9785
  "enum": [
8731
- "totp"
9786
+ "email"
8732
9787
  ]
8733
9788
  },
8734
9789
  {
8735
9790
  "type": "string",
8736
9791
  "enum": [
8737
- "webauthn"
9792
+ "sms"
9793
+ ]
9794
+ },
9795
+ {
9796
+ "type": "string",
9797
+ "enum": [
9798
+ "whatsapp"
9799
+ ]
9800
+ },
9801
+ {
9802
+ "type": "string",
9803
+ "enum": [
9804
+ "factor"
8738
9805
  ]
8739
9806
  }
8740
9807
  ]
8741
9808
  },
8742
- "description": "Which kinds of second factor satisfy the policy. Empty or unset means all of them. A user whose only factor is of a kind not listed here is treated as having none."
8743
- },
8744
- "remember_device_days": {
8745
- "type": "integer",
8746
- "minimum": 0,
8747
- "maximum": 365,
8748
- "description": "How long a browser that already passed a challenge may skip the next one. 0 (default) challenges every time."
9809
+ "description": "Channels the recovery screen offers the user to pick from, after they enter their identifier. Empty (the default) keeps today's behaviour: the default channel is used silently and the response never reveals whether the account exists. A non-empty list shows a picker with masked destinations — which does reveal that the account exists and which channels it has, the same trade-off Google and Microsoft make. A tenant decision."
8749
9810
  }
8750
9811
  },
8751
9812
  "additionalProperties": false,
8752
- "description": "Second-factor policy. Set on the Account as the tenant default; the same object on a Client overrides it **field by field**, so one app can require MFA without changing the rest."
9813
+ "description": "Password-recovery delivery channels. Set on the Account as the tenant default; the same object on a Client overrides it field by field, like `login_methods` and `mfa_policy`."
8753
9814
  },
8754
9815
  "webauthn_rp_id": {
8755
9816
  "type": "string",
@@ -8773,6 +9834,252 @@
8773
9834
  }
8774
9835
  }
8775
9836
  },
9837
+ "/recovery-channels/capabilities": {
9838
+ "get": {
9839
+ "operationId": "account/recoveryChannelsCapabilities",
9840
+ "summary": "Recovery channel capabilities for this tenant",
9841
+ "tags": [
9842
+ "account"
9843
+ ],
9844
+ "description": "Which recovery channels the platform can send, whether the plan allows the paid ones, this month's SMS usage against the included amount, and the tenant configuration as resolved. Drives the \"Recovery channels\" editor in the dashboard.",
9845
+ "security": [
9846
+ {
9847
+ "bearerAuth": []
9848
+ }
9849
+ ],
9850
+ "responses": {
9851
+ "200": {
9852
+ "description": "Default Response",
9853
+ "content": {
9854
+ "application/json": {
9855
+ "schema": {
9856
+ "type": "object",
9857
+ "required": [
9858
+ "provider",
9859
+ "plan",
9860
+ "usage",
9861
+ "resolved",
9862
+ "channels"
9863
+ ],
9864
+ "properties": {
9865
+ "provider": {
9866
+ "type": "object",
9867
+ "required": [
9868
+ "sms",
9869
+ "whatsapp"
9870
+ ],
9871
+ "properties": {
9872
+ "sms": {
9873
+ "type": "boolean"
9874
+ },
9875
+ "whatsapp": {
9876
+ "type": "boolean"
9877
+ }
9878
+ },
9879
+ "description": "Whether the platform can send on each channel right now."
9880
+ },
9881
+ "plan": {
9882
+ "type": "object",
9883
+ "required": [
9884
+ "known",
9885
+ "allows_messaging"
9886
+ ],
9887
+ "properties": {
9888
+ "known": {
9889
+ "type": "boolean",
9890
+ "description": "False when billing did not answer. Messaging channels are then treated as not allowed — the failure mode for a paid-per-message channel is \"do not send\", not \"allow\"."
9891
+ },
9892
+ "tier": {
9893
+ "type": "string"
9894
+ },
9895
+ "allows_messaging": {
9896
+ "type": "boolean"
9897
+ }
9898
+ }
9899
+ },
9900
+ "usage": {
9901
+ "type": "object",
9902
+ "required": [
9903
+ "month",
9904
+ "sent",
9905
+ "included",
9906
+ "metered",
9907
+ "hard_ceiling"
9908
+ ],
9909
+ "properties": {
9910
+ "month": {
9911
+ "type": "string",
9912
+ "description": "YYYY-MM, UTC."
9913
+ },
9914
+ "sent": {
9915
+ "type": "integer"
9916
+ },
9917
+ "included": {
9918
+ "type": "integer"
9919
+ },
9920
+ "metered": {
9921
+ "type": "boolean"
9922
+ },
9923
+ "hard_ceiling": {
9924
+ "type": "integer"
9925
+ }
9926
+ }
9927
+ },
9928
+ "resolved": {
9929
+ "type": "object",
9930
+ "required": [
9931
+ "enabled",
9932
+ "default",
9933
+ "visible"
9934
+ ],
9935
+ "properties": {
9936
+ "enabled": {
9937
+ "type": "array",
9938
+ "items": {
9939
+ "anyOf": [
9940
+ {
9941
+ "type": "string",
9942
+ "enum": [
9943
+ "email"
9944
+ ]
9945
+ },
9946
+ {
9947
+ "type": "string",
9948
+ "enum": [
9949
+ "sms"
9950
+ ]
9951
+ },
9952
+ {
9953
+ "type": "string",
9954
+ "enum": [
9955
+ "whatsapp"
9956
+ ]
9957
+ },
9958
+ {
9959
+ "type": "string",
9960
+ "enum": [
9961
+ "factor"
9962
+ ]
9963
+ }
9964
+ ]
9965
+ }
9966
+ },
9967
+ "default": {
9968
+ "anyOf": [
9969
+ {
9970
+ "type": "string",
9971
+ "enum": [
9972
+ "email"
9973
+ ]
9974
+ },
9975
+ {
9976
+ "type": "string",
9977
+ "enum": [
9978
+ "sms"
9979
+ ]
9980
+ },
9981
+ {
9982
+ "type": "string",
9983
+ "enum": [
9984
+ "whatsapp"
9985
+ ]
9986
+ },
9987
+ {
9988
+ "type": "string",
9989
+ "enum": [
9990
+ "factor"
9991
+ ]
9992
+ }
9993
+ ]
9994
+ },
9995
+ "visible": {
9996
+ "type": "array",
9997
+ "items": {
9998
+ "anyOf": [
9999
+ {
10000
+ "type": "string",
10001
+ "enum": [
10002
+ "email"
10003
+ ]
10004
+ },
10005
+ {
10006
+ "type": "string",
10007
+ "enum": [
10008
+ "sms"
10009
+ ]
10010
+ },
10011
+ {
10012
+ "type": "string",
10013
+ "enum": [
10014
+ "whatsapp"
10015
+ ]
10016
+ },
10017
+ {
10018
+ "type": "string",
10019
+ "enum": [
10020
+ "factor"
10021
+ ]
10022
+ }
10023
+ ]
10024
+ }
10025
+ }
10026
+ }
10027
+ },
10028
+ "channels": {
10029
+ "type": "array",
10030
+ "items": {
10031
+ "type": "object",
10032
+ "required": [
10033
+ "channel",
10034
+ "available"
10035
+ ],
10036
+ "properties": {
10037
+ "channel": {
10038
+ "anyOf": [
10039
+ {
10040
+ "type": "string",
10041
+ "enum": [
10042
+ "email"
10043
+ ]
10044
+ },
10045
+ {
10046
+ "type": "string",
10047
+ "enum": [
10048
+ "sms"
10049
+ ]
10050
+ },
10051
+ {
10052
+ "type": "string",
10053
+ "enum": [
10054
+ "whatsapp"
10055
+ ]
10056
+ },
10057
+ {
10058
+ "type": "string",
10059
+ "enum": [
10060
+ "factor"
10061
+ ]
10062
+ }
10063
+ ]
10064
+ },
10065
+ "available": {
10066
+ "type": "boolean"
10067
+ },
10068
+ "reason": {
10069
+ "type": "string"
10070
+ }
10071
+ }
10072
+ },
10073
+ "description": "Tenant-level availability (configuration × platform × plan). The per-user step — verified phone, enrolled factor — is not applied here."
10074
+ }
10075
+ }
10076
+ }
10077
+ }
10078
+ }
10079
+ }
10080
+ }
10081
+ }
10082
+ },
8776
10083
  "/connection": {
8777
10084
  "get": {
8778
10085
  "operationId": "connection/list",
@@ -10802,75 +12109,179 @@
10802
12109
  ],
10803
12110
  "description": "Show a \"Remember me on this device\" checkbox on the password and email-code forms. `optional`: unchecked, the session ends when the browser closes; checked, it lasts `remember_me_days`. `off` (the default): no checkbox, every session lasts the built-in 30 days."
10804
12111
  },
10805
- "remember_me_days": {
12112
+ "remember_me_days": {
12113
+ "type": "integer",
12114
+ "minimum": 1,
12115
+ "maximum": 365,
12116
+ "description": "How long a session lasts when the user ticked \"Remember me\". Defaults to 30."
12117
+ }
12118
+ },
12119
+ "additionalProperties": false,
12120
+ "description": "Which login methods the hosted login screen offers and in what order. Set on the Account as the tenant default; the same object on a Client overrides it **field by field**, so a client can flip one flag without restating the rest. Absent everywhere = built-in defaults."
12121
+ },
12122
+ "mfa_policy": {
12123
+ "type": "object",
12124
+ "properties": {
12125
+ "mode": {
12126
+ "anyOf": [
12127
+ {
12128
+ "anyOf": [
12129
+ {
12130
+ "type": "string",
12131
+ "enum": [
12132
+ "off"
12133
+ ]
12134
+ },
12135
+ {
12136
+ "type": "string",
12137
+ "enum": [
12138
+ "optional"
12139
+ ]
12140
+ },
12141
+ {
12142
+ "type": "string",
12143
+ "enum": [
12144
+ "required"
12145
+ ]
12146
+ }
12147
+ ]
12148
+ }
12149
+ ],
12150
+ "description": "`off` (default) never challenges. `optional` challenges a user who has enrolled a factor, and lets everyone else in. `required` challenges everyone and sends users with no factor through enrolment during login — it never locks anyone out in place."
12151
+ },
12152
+ "allowed_factors": {
12153
+ "type": "array",
12154
+ "items": {
12155
+ "anyOf": [
12156
+ {
12157
+ "type": "string",
12158
+ "enum": [
12159
+ "totp"
12160
+ ]
12161
+ },
12162
+ {
12163
+ "type": "string",
12164
+ "enum": [
12165
+ "webauthn"
12166
+ ]
12167
+ }
12168
+ ]
12169
+ },
12170
+ "description": "Which kinds of second factor satisfy the policy. Empty or unset means all of them. A user whose only factor is of a kind not listed here is treated as having none."
12171
+ },
12172
+ "remember_device_days": {
10806
12173
  "type": "integer",
10807
- "minimum": 1,
12174
+ "minimum": 0,
10808
12175
  "maximum": 365,
10809
- "description": "How long a session lasts when the user ticked \"Remember me\". Defaults to 30."
12176
+ "description": "How long a browser that already passed a challenge may skip the next one. 0 (default) challenges every time."
10810
12177
  }
10811
12178
  },
10812
12179
  "additionalProperties": false,
10813
- "description": "Which login methods the hosted login screen offers and in what order. Set on the Account as the tenant default; the same object on a Client overrides it **field by field**, so a client can flip one flag without restating the rest. Absent everywhere = built-in defaults."
12180
+ "description": "Second-factor policy. Set on the Account as the tenant default; the same object on a Client overrides it **field by field**, so one app can require MFA without changing the rest."
10814
12181
  },
10815
- "mfa_policy": {
12182
+ "recovery_channels": {
10816
12183
  "type": "object",
10817
12184
  "properties": {
10818
- "mode": {
12185
+ "enabled": {
12186
+ "type": "array",
12187
+ "items": {
12188
+ "anyOf": [
12189
+ {
12190
+ "type": "string",
12191
+ "enum": [
12192
+ "email"
12193
+ ]
12194
+ },
12195
+ {
12196
+ "type": "string",
12197
+ "enum": [
12198
+ "sms"
12199
+ ]
12200
+ },
12201
+ {
12202
+ "type": "string",
12203
+ "enum": [
12204
+ "whatsapp"
12205
+ ]
12206
+ },
12207
+ {
12208
+ "type": "string",
12209
+ "enum": [
12210
+ "factor"
12211
+ ]
12212
+ }
12213
+ ]
12214
+ },
12215
+ "description": "Channels the tenant has turned on. `email` is always on regardless of this list: it is what every other channel falls back to. A channel listed here is still offered only if the platform can send it, the plan allows it and the user has a verified destination for it."
12216
+ },
12217
+ "default": {
10819
12218
  "anyOf": [
10820
12219
  {
10821
12220
  "anyOf": [
10822
12221
  {
10823
12222
  "type": "string",
10824
12223
  "enum": [
10825
- "off"
12224
+ "email"
10826
12225
  ]
10827
12226
  },
10828
12227
  {
10829
12228
  "type": "string",
10830
12229
  "enum": [
10831
- "optional"
12230
+ "sms"
10832
12231
  ]
10833
12232
  },
10834
12233
  {
10835
12234
  "type": "string",
10836
12235
  "enum": [
10837
- "required"
12236
+ "whatsapp"
12237
+ ]
12238
+ },
12239
+ {
12240
+ "type": "string",
12241
+ "enum": [
12242
+ "factor"
10838
12243
  ]
10839
12244
  }
10840
12245
  ]
10841
12246
  }
10842
12247
  ],
10843
- "description": "`off` (default) never challenges. `optional` challenges a user who has enrolled a factor, and lets everyone else in. `required` challenges everyone and sends users with no factor through enrolment during login — it never locks anyone out in place."
12248
+ "description": "The channel used when the user is not asked to choose. Falls back to `email` when it is not available for that user."
10844
12249
  },
10845
- "allowed_factors": {
12250
+ "visible": {
10846
12251
  "type": "array",
10847
12252
  "items": {
10848
12253
  "anyOf": [
10849
12254
  {
10850
12255
  "type": "string",
10851
12256
  "enum": [
10852
- "totp"
12257
+ "email"
10853
12258
  ]
10854
12259
  },
10855
12260
  {
10856
12261
  "type": "string",
10857
12262
  "enum": [
10858
- "webauthn"
12263
+ "sms"
12264
+ ]
12265
+ },
12266
+ {
12267
+ "type": "string",
12268
+ "enum": [
12269
+ "whatsapp"
12270
+ ]
12271
+ },
12272
+ {
12273
+ "type": "string",
12274
+ "enum": [
12275
+ "factor"
10859
12276
  ]
10860
12277
  }
10861
12278
  ]
10862
12279
  },
10863
- "description": "Which kinds of second factor satisfy the policy. Empty or unset means all of them. A user whose only factor is of a kind not listed here is treated as having none."
10864
- },
10865
- "remember_device_days": {
10866
- "type": "integer",
10867
- "minimum": 0,
10868
- "maximum": 365,
10869
- "description": "How long a browser that already passed a challenge may skip the next one. 0 (default) challenges every time."
12280
+ "description": "Channels the recovery screen offers the user to pick from, after they enter their identifier. Empty (the default) keeps today's behaviour: the default channel is used silently and the response never reveals whether the account exists. A non-empty list shows a picker with masked destinations — which does reveal that the account exists and which channels it has, the same trade-off Google and Microsoft make. A tenant decision."
10870
12281
  }
10871
12282
  },
10872
12283
  "additionalProperties": false,
10873
- "description": "Second-factor policy. Set on the Account as the tenant default; the same object on a Client overrides it **field by field**, so one app can require MFA without changing the rest."
12284
+ "description": "Password-recovery delivery channels. Set on the Account as the tenant default; the same object on a Client overrides it field by field, like `login_methods` and `mfa_policy`."
10874
12285
  },
10875
12286
  "login_flow": {
10876
12287
  "anyOf": [
@@ -11222,6 +12633,110 @@
11222
12633
  "additionalProperties": false,
11223
12634
  "description": "Second-factor policy. Set on the Account as the tenant default; the same object on a Client overrides it **field by field**, so one app can require MFA without changing the rest."
11224
12635
  },
12636
+ "recovery_channels": {
12637
+ "type": "object",
12638
+ "properties": {
12639
+ "enabled": {
12640
+ "type": "array",
12641
+ "items": {
12642
+ "anyOf": [
12643
+ {
12644
+ "type": "string",
12645
+ "enum": [
12646
+ "email"
12647
+ ]
12648
+ },
12649
+ {
12650
+ "type": "string",
12651
+ "enum": [
12652
+ "sms"
12653
+ ]
12654
+ },
12655
+ {
12656
+ "type": "string",
12657
+ "enum": [
12658
+ "whatsapp"
12659
+ ]
12660
+ },
12661
+ {
12662
+ "type": "string",
12663
+ "enum": [
12664
+ "factor"
12665
+ ]
12666
+ }
12667
+ ]
12668
+ },
12669
+ "description": "Channels the tenant has turned on. `email` is always on regardless of this list: it is what every other channel falls back to. A channel listed here is still offered only if the platform can send it, the plan allows it and the user has a verified destination for it."
12670
+ },
12671
+ "default": {
12672
+ "anyOf": [
12673
+ {
12674
+ "anyOf": [
12675
+ {
12676
+ "type": "string",
12677
+ "enum": [
12678
+ "email"
12679
+ ]
12680
+ },
12681
+ {
12682
+ "type": "string",
12683
+ "enum": [
12684
+ "sms"
12685
+ ]
12686
+ },
12687
+ {
12688
+ "type": "string",
12689
+ "enum": [
12690
+ "whatsapp"
12691
+ ]
12692
+ },
12693
+ {
12694
+ "type": "string",
12695
+ "enum": [
12696
+ "factor"
12697
+ ]
12698
+ }
12699
+ ]
12700
+ }
12701
+ ],
12702
+ "description": "The channel used when the user is not asked to choose. Falls back to `email` when it is not available for that user."
12703
+ },
12704
+ "visible": {
12705
+ "type": "array",
12706
+ "items": {
12707
+ "anyOf": [
12708
+ {
12709
+ "type": "string",
12710
+ "enum": [
12711
+ "email"
12712
+ ]
12713
+ },
12714
+ {
12715
+ "type": "string",
12716
+ "enum": [
12717
+ "sms"
12718
+ ]
12719
+ },
12720
+ {
12721
+ "type": "string",
12722
+ "enum": [
12723
+ "whatsapp"
12724
+ ]
12725
+ },
12726
+ {
12727
+ "type": "string",
12728
+ "enum": [
12729
+ "factor"
12730
+ ]
12731
+ }
12732
+ ]
12733
+ },
12734
+ "description": "Channels the recovery screen offers the user to pick from, after they enter their identifier. Empty (the default) keeps today's behaviour: the default channel is used silently and the response never reveals whether the account exists. A non-empty list shows a picker with masked destinations — which does reveal that the account exists and which channels it has, the same trade-off Google and Microsoft make. A tenant decision."
12735
+ }
12736
+ },
12737
+ "additionalProperties": false,
12738
+ "description": "Password-recovery delivery channels. Set on the Account as the tenant default; the same object on a Client overrides it field by field, like `login_methods` and `mfa_policy`."
12739
+ },
11225
12740
  "login_flow": {
11226
12741
  "anyOf": [
11227
12742
  {
@@ -11542,7 +13057,118 @@
11542
13057
  }
11543
13058
  },
11544
13059
  "additionalProperties": false,
11545
- "description": "Second-factor policy. Set on the Account as the tenant default; the same object on a Client overrides it **field by field**, so one app can require MFA without changing the rest."
13060
+ "description": "Second-factor policy. Set on the Account as the tenant default; the same object on a Client overrides it **field by field**, so one app can require MFA without changing the rest."
13061
+ },
13062
+ {
13063
+ "type": "null"
13064
+ }
13065
+ ]
13066
+ },
13067
+ "recovery_channels": {
13068
+ "anyOf": [
13069
+ {
13070
+ "type": "object",
13071
+ "properties": {
13072
+ "enabled": {
13073
+ "type": "array",
13074
+ "items": {
13075
+ "anyOf": [
13076
+ {
13077
+ "type": "string",
13078
+ "enum": [
13079
+ "email"
13080
+ ]
13081
+ },
13082
+ {
13083
+ "type": "string",
13084
+ "enum": [
13085
+ "sms"
13086
+ ]
13087
+ },
13088
+ {
13089
+ "type": "string",
13090
+ "enum": [
13091
+ "whatsapp"
13092
+ ]
13093
+ },
13094
+ {
13095
+ "type": "string",
13096
+ "enum": [
13097
+ "factor"
13098
+ ]
13099
+ }
13100
+ ]
13101
+ },
13102
+ "description": "Channels the tenant has turned on. `email` is always on regardless of this list: it is what every other channel falls back to. A channel listed here is still offered only if the platform can send it, the plan allows it and the user has a verified destination for it."
13103
+ },
13104
+ "default": {
13105
+ "anyOf": [
13106
+ {
13107
+ "anyOf": [
13108
+ {
13109
+ "type": "string",
13110
+ "enum": [
13111
+ "email"
13112
+ ]
13113
+ },
13114
+ {
13115
+ "type": "string",
13116
+ "enum": [
13117
+ "sms"
13118
+ ]
13119
+ },
13120
+ {
13121
+ "type": "string",
13122
+ "enum": [
13123
+ "whatsapp"
13124
+ ]
13125
+ },
13126
+ {
13127
+ "type": "string",
13128
+ "enum": [
13129
+ "factor"
13130
+ ]
13131
+ }
13132
+ ]
13133
+ }
13134
+ ],
13135
+ "description": "The channel used when the user is not asked to choose. Falls back to `email` when it is not available for that user."
13136
+ },
13137
+ "visible": {
13138
+ "type": "array",
13139
+ "items": {
13140
+ "anyOf": [
13141
+ {
13142
+ "type": "string",
13143
+ "enum": [
13144
+ "email"
13145
+ ]
13146
+ },
13147
+ {
13148
+ "type": "string",
13149
+ "enum": [
13150
+ "sms"
13151
+ ]
13152
+ },
13153
+ {
13154
+ "type": "string",
13155
+ "enum": [
13156
+ "whatsapp"
13157
+ ]
13158
+ },
13159
+ {
13160
+ "type": "string",
13161
+ "enum": [
13162
+ "factor"
13163
+ ]
13164
+ }
13165
+ ]
13166
+ },
13167
+ "description": "Channels the recovery screen offers the user to pick from, after they enter their identifier. Empty (the default) keeps today's behaviour: the default channel is used silently and the response never reveals whether the account exists. A non-empty list shows a picker with masked destinations — which does reveal that the account exists and which channels it has, the same trade-off Google and Microsoft make. A tenant decision."
13168
+ }
13169
+ },
13170
+ "additionalProperties": false,
13171
+ "description": "Password-recovery delivery channels. Set on the Account as the tenant default; the same object on a Client overrides it field by field, like `login_methods` and `mfa_policy`."
11546
13172
  },
11547
13173
  {
11548
13174
  "type": "null"
@@ -11877,6 +13503,110 @@
11877
13503
  "additionalProperties": false,
11878
13504
  "description": "Second-factor policy. Set on the Account as the tenant default; the same object on a Client overrides it **field by field**, so one app can require MFA without changing the rest."
11879
13505
  },
13506
+ "recovery_channels": {
13507
+ "type": "object",
13508
+ "properties": {
13509
+ "enabled": {
13510
+ "type": "array",
13511
+ "items": {
13512
+ "anyOf": [
13513
+ {
13514
+ "type": "string",
13515
+ "enum": [
13516
+ "email"
13517
+ ]
13518
+ },
13519
+ {
13520
+ "type": "string",
13521
+ "enum": [
13522
+ "sms"
13523
+ ]
13524
+ },
13525
+ {
13526
+ "type": "string",
13527
+ "enum": [
13528
+ "whatsapp"
13529
+ ]
13530
+ },
13531
+ {
13532
+ "type": "string",
13533
+ "enum": [
13534
+ "factor"
13535
+ ]
13536
+ }
13537
+ ]
13538
+ },
13539
+ "description": "Channels the tenant has turned on. `email` is always on regardless of this list: it is what every other channel falls back to. A channel listed here is still offered only if the platform can send it, the plan allows it and the user has a verified destination for it."
13540
+ },
13541
+ "default": {
13542
+ "anyOf": [
13543
+ {
13544
+ "anyOf": [
13545
+ {
13546
+ "type": "string",
13547
+ "enum": [
13548
+ "email"
13549
+ ]
13550
+ },
13551
+ {
13552
+ "type": "string",
13553
+ "enum": [
13554
+ "sms"
13555
+ ]
13556
+ },
13557
+ {
13558
+ "type": "string",
13559
+ "enum": [
13560
+ "whatsapp"
13561
+ ]
13562
+ },
13563
+ {
13564
+ "type": "string",
13565
+ "enum": [
13566
+ "factor"
13567
+ ]
13568
+ }
13569
+ ]
13570
+ }
13571
+ ],
13572
+ "description": "The channel used when the user is not asked to choose. Falls back to `email` when it is not available for that user."
13573
+ },
13574
+ "visible": {
13575
+ "type": "array",
13576
+ "items": {
13577
+ "anyOf": [
13578
+ {
13579
+ "type": "string",
13580
+ "enum": [
13581
+ "email"
13582
+ ]
13583
+ },
13584
+ {
13585
+ "type": "string",
13586
+ "enum": [
13587
+ "sms"
13588
+ ]
13589
+ },
13590
+ {
13591
+ "type": "string",
13592
+ "enum": [
13593
+ "whatsapp"
13594
+ ]
13595
+ },
13596
+ {
13597
+ "type": "string",
13598
+ "enum": [
13599
+ "factor"
13600
+ ]
13601
+ }
13602
+ ]
13603
+ },
13604
+ "description": "Channels the recovery screen offers the user to pick from, after they enter their identifier. Empty (the default) keeps today's behaviour: the default channel is used silently and the response never reveals whether the account exists. A non-empty list shows a picker with masked destinations — which does reveal that the account exists and which channels it has, the same trade-off Google and Microsoft make. A tenant decision."
13605
+ }
13606
+ },
13607
+ "additionalProperties": false,
13608
+ "description": "Password-recovery delivery channels. Set on the Account as the tenant default; the same object on a Client overrides it field by field, like `login_methods` and `mfa_policy`."
13609
+ },
11880
13610
  "login_flow": {
11881
13611
  "anyOf": [
11882
13612
  {
@@ -12225,6 +13955,110 @@
12225
13955
  "additionalProperties": false,
12226
13956
  "description": "Second-factor policy. Set on the Account as the tenant default; the same object on a Client overrides it **field by field**, so one app can require MFA without changing the rest."
12227
13957
  },
13958
+ "recovery_channels": {
13959
+ "type": "object",
13960
+ "properties": {
13961
+ "enabled": {
13962
+ "type": "array",
13963
+ "items": {
13964
+ "anyOf": [
13965
+ {
13966
+ "type": "string",
13967
+ "enum": [
13968
+ "email"
13969
+ ]
13970
+ },
13971
+ {
13972
+ "type": "string",
13973
+ "enum": [
13974
+ "sms"
13975
+ ]
13976
+ },
13977
+ {
13978
+ "type": "string",
13979
+ "enum": [
13980
+ "whatsapp"
13981
+ ]
13982
+ },
13983
+ {
13984
+ "type": "string",
13985
+ "enum": [
13986
+ "factor"
13987
+ ]
13988
+ }
13989
+ ]
13990
+ },
13991
+ "description": "Channels the tenant has turned on. `email` is always on regardless of this list: it is what every other channel falls back to. A channel listed here is still offered only if the platform can send it, the plan allows it and the user has a verified destination for it."
13992
+ },
13993
+ "default": {
13994
+ "anyOf": [
13995
+ {
13996
+ "anyOf": [
13997
+ {
13998
+ "type": "string",
13999
+ "enum": [
14000
+ "email"
14001
+ ]
14002
+ },
14003
+ {
14004
+ "type": "string",
14005
+ "enum": [
14006
+ "sms"
14007
+ ]
14008
+ },
14009
+ {
14010
+ "type": "string",
14011
+ "enum": [
14012
+ "whatsapp"
14013
+ ]
14014
+ },
14015
+ {
14016
+ "type": "string",
14017
+ "enum": [
14018
+ "factor"
14019
+ ]
14020
+ }
14021
+ ]
14022
+ }
14023
+ ],
14024
+ "description": "The channel used when the user is not asked to choose. Falls back to `email` when it is not available for that user."
14025
+ },
14026
+ "visible": {
14027
+ "type": "array",
14028
+ "items": {
14029
+ "anyOf": [
14030
+ {
14031
+ "type": "string",
14032
+ "enum": [
14033
+ "email"
14034
+ ]
14035
+ },
14036
+ {
14037
+ "type": "string",
14038
+ "enum": [
14039
+ "sms"
14040
+ ]
14041
+ },
14042
+ {
14043
+ "type": "string",
14044
+ "enum": [
14045
+ "whatsapp"
14046
+ ]
14047
+ },
14048
+ {
14049
+ "type": "string",
14050
+ "enum": [
14051
+ "factor"
14052
+ ]
14053
+ }
14054
+ ]
14055
+ },
14056
+ "description": "Channels the recovery screen offers the user to pick from, after they enter their identifier. Empty (the default) keeps today's behaviour: the default channel is used silently and the response never reveals whether the account exists. A non-empty list shows a picker with masked destinations — which does reveal that the account exists and which channels it has, the same trade-off Google and Microsoft make. A tenant decision."
14057
+ }
14058
+ },
14059
+ "additionalProperties": false,
14060
+ "description": "Password-recovery delivery channels. Set on the Account as the tenant default; the same object on a Client overrides it field by field, like `login_methods` and `mfa_policy`."
14061
+ },
12228
14062
  "login_flow": {
12229
14063
  "anyOf": [
12230
14064
  {
@@ -12575,6 +14409,110 @@
12575
14409
  "additionalProperties": false,
12576
14410
  "description": "Second-factor policy. Set on the Account as the tenant default; the same object on a Client overrides it **field by field**, so one app can require MFA without changing the rest."
12577
14411
  },
14412
+ "recovery_channels": {
14413
+ "type": "object",
14414
+ "properties": {
14415
+ "enabled": {
14416
+ "type": "array",
14417
+ "items": {
14418
+ "anyOf": [
14419
+ {
14420
+ "type": "string",
14421
+ "enum": [
14422
+ "email"
14423
+ ]
14424
+ },
14425
+ {
14426
+ "type": "string",
14427
+ "enum": [
14428
+ "sms"
14429
+ ]
14430
+ },
14431
+ {
14432
+ "type": "string",
14433
+ "enum": [
14434
+ "whatsapp"
14435
+ ]
14436
+ },
14437
+ {
14438
+ "type": "string",
14439
+ "enum": [
14440
+ "factor"
14441
+ ]
14442
+ }
14443
+ ]
14444
+ },
14445
+ "description": "Channels the tenant has turned on. `email` is always on regardless of this list: it is what every other channel falls back to. A channel listed here is still offered only if the platform can send it, the plan allows it and the user has a verified destination for it."
14446
+ },
14447
+ "default": {
14448
+ "anyOf": [
14449
+ {
14450
+ "anyOf": [
14451
+ {
14452
+ "type": "string",
14453
+ "enum": [
14454
+ "email"
14455
+ ]
14456
+ },
14457
+ {
14458
+ "type": "string",
14459
+ "enum": [
14460
+ "sms"
14461
+ ]
14462
+ },
14463
+ {
14464
+ "type": "string",
14465
+ "enum": [
14466
+ "whatsapp"
14467
+ ]
14468
+ },
14469
+ {
14470
+ "type": "string",
14471
+ "enum": [
14472
+ "factor"
14473
+ ]
14474
+ }
14475
+ ]
14476
+ }
14477
+ ],
14478
+ "description": "The channel used when the user is not asked to choose. Falls back to `email` when it is not available for that user."
14479
+ },
14480
+ "visible": {
14481
+ "type": "array",
14482
+ "items": {
14483
+ "anyOf": [
14484
+ {
14485
+ "type": "string",
14486
+ "enum": [
14487
+ "email"
14488
+ ]
14489
+ },
14490
+ {
14491
+ "type": "string",
14492
+ "enum": [
14493
+ "sms"
14494
+ ]
14495
+ },
14496
+ {
14497
+ "type": "string",
14498
+ "enum": [
14499
+ "whatsapp"
14500
+ ]
14501
+ },
14502
+ {
14503
+ "type": "string",
14504
+ "enum": [
14505
+ "factor"
14506
+ ]
14507
+ }
14508
+ ]
14509
+ },
14510
+ "description": "Channels the recovery screen offers the user to pick from, after they enter their identifier. Empty (the default) keeps today's behaviour: the default channel is used silently and the response never reveals whether the account exists. A non-empty list shows a picker with masked destinations — which does reveal that the account exists and which channels it has, the same trade-off Google and Microsoft make. A tenant decision."
14511
+ }
14512
+ },
14513
+ "additionalProperties": false,
14514
+ "description": "Password-recovery delivery channels. Set on the Account as the tenant default; the same object on a Client overrides it field by field, like `login_methods` and `mfa_policy`."
14515
+ },
12578
14516
  "login_flow": {
12579
14517
  "anyOf": [
12580
14518
  {