@faable/auth-sdk 1.3.12 → 1.3.14

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.
@@ -132,7 +132,11 @@ export interface paths {
132
132
  */
133
133
  get: operations["connection/get"];
134
134
  put?: never;
135
- post?: never;
135
+ /**
136
+ * Update Connections in Account
137
+ * @description Update Connections in Account
138
+ */
139
+ post: operations["connection/update"];
136
140
  /**
137
141
  * Delete Connection in Account
138
142
  * @description Delete Connection in Account
@@ -180,7 +184,11 @@ export interface paths {
180
184
  */
181
185
  get: operations["client/get"];
182
186
  put?: never;
183
- post?: never;
187
+ /**
188
+ * Update Clients in Account
189
+ * @description Update Clients in Account
190
+ */
191
+ post: operations["client/update"];
184
192
  /**
185
193
  * Delete Client in Account
186
194
  * @description Delete Client in Account
@@ -191,6 +199,26 @@ export interface paths {
191
199
  patch?: never;
192
200
  trace?: never;
193
201
  };
202
+ "/client/{client_id}/rotate-secret": {
203
+ parameters: {
204
+ query?: never;
205
+ header?: never;
206
+ path?: never;
207
+ cookie?: never;
208
+ };
209
+ get?: never;
210
+ put?: never;
211
+ /**
212
+ * Rotate a Client's secret
213
+ * @description Generates a fresh `client_secret` for the given Client and persists it. The previous secret is invalidated immediately — there is no grace period. Returns the full Client; the dashboard must surface the new secret to the admin once. Existing client_credentials / authorization_code integrations using the old secret will start failing at the token endpoint immediately after this call.
214
+ */
215
+ post: operations["client/rotateSecret"];
216
+ delete?: never;
217
+ options?: never;
218
+ head?: never;
219
+ patch?: never;
220
+ trace?: never;
221
+ };
194
222
  "/user": {
195
223
  parameters: {
196
224
  query?: never;
@@ -243,6 +271,86 @@ export interface paths {
243
271
  patch?: never;
244
272
  trace?: never;
245
273
  };
274
+ "/user/{user_id}/change-email": {
275
+ parameters: {
276
+ query?: never;
277
+ header?: never;
278
+ path?: never;
279
+ cookie?: never;
280
+ };
281
+ get?: never;
282
+ put?: never;
283
+ /**
284
+ * Start the user's email change flow
285
+ * @description Initiates the email-change flow for the given user. Validates the new email, ensures it is not already in use in the tenant, revokes any pending change for the same user, creates a Ticket (`type='change_email'`), and sends a verification email to the new address. Re-authentication is not required — an active session/Bearer is enough. The change does NOT take effect until the user clicks the link in the email and confirms via `/change-email-confirm`.
286
+ */
287
+ post: operations["user/changeEmail"];
288
+ delete?: never;
289
+ options?: never;
290
+ head?: never;
291
+ patch?: never;
292
+ trace?: never;
293
+ };
294
+ "/change-email-verify": {
295
+ parameters: {
296
+ query?: never;
297
+ header?: never;
298
+ path?: never;
299
+ cookie?: never;
300
+ };
301
+ /**
302
+ * Verify a change-email ticket and apply the change
303
+ * @description Entry point for the link sent to the new email. Consumes the ticket, applies the email swap (in `new_only` mode) or issues a secondary verification ticket to the old email (in `old_and_new` mode, first step). Redirects to the `redirect_uri` supplied at flow start with `?status=applied|pending_old` appended; falls back to `/flow/email-change-done` on the auth host when no `redirect_uri` was given.
304
+ */
305
+ get: operations["user_change_email_verify"];
306
+ put?: never;
307
+ post?: never;
308
+ delete?: never;
309
+ options?: never;
310
+ head?: never;
311
+ patch?: never;
312
+ trace?: never;
313
+ };
314
+ "/user/{user_id}/verify-email/start": {
315
+ parameters: {
316
+ query?: never;
317
+ header?: never;
318
+ path?: never;
319
+ cookie?: never;
320
+ };
321
+ get?: never;
322
+ put?: never;
323
+ /**
324
+ * Start the user's email verification flow
325
+ * @description Initiates the email-verification flow for the given user. Creates a `verify_email` Ticket and queues the verification email. Idempotent — returns `{status:'already_verified'}` without emitting a ticket if the user is already verified. Re-authentication is not required: an active session/Bearer is enough.
326
+ */
327
+ post: operations["user/verifyEmailStart"];
328
+ delete?: never;
329
+ options?: never;
330
+ head?: never;
331
+ patch?: never;
332
+ trace?: never;
333
+ };
334
+ "/verify-email": {
335
+ parameters: {
336
+ query?: never;
337
+ header?: never;
338
+ path?: never;
339
+ cookie?: never;
340
+ };
341
+ /**
342
+ * Verify a verify-email ticket and mark the user verified
343
+ * @description Entry point for the link sent to the user. Consumes the ticket, sets `email_verified=true` with `email_verified_method='verification_flow'`. Redirects to the `redirect_uri` supplied at start with `?status=verified|already_verified` appended; falls back to `/flow/verify-email-done` on the auth host when no `redirect_uri` was given. Invalid/expired tickets redirect to the same fallback with `?status=invalid_link` or `?status=expired`.
344
+ */
345
+ get: operations["user_verify_email_confirm"];
346
+ put?: never;
347
+ post?: never;
348
+ delete?: never;
349
+ options?: never;
350
+ head?: never;
351
+ patch?: never;
352
+ trace?: never;
353
+ };
246
354
  "/identity": {
247
355
  parameters: {
248
356
  query?: never;
@@ -328,7 +436,11 @@ export interface paths {
328
436
  */
329
437
  get: operations["role/get"];
330
438
  put?: never;
331
- post?: never;
439
+ /**
440
+ * Update Roles in Account
441
+ * @description Update Roles in Account
442
+ */
443
+ post: operations["role/update"];
332
444
  /**
333
445
  * Delete Role in Account
334
446
  * @description Delete Role in Account
@@ -448,7 +560,11 @@ export interface paths {
448
560
  */
449
561
  get: operations["team/get"];
450
562
  put?: never;
451
- post?: never;
563
+ /**
564
+ * Update Teams in Account
565
+ * @description Update Teams in Account
566
+ */
567
+ post: operations["team/update"];
452
568
  /**
453
569
  * Delete Team in Account
454
570
  * @description Delete Team in Account
@@ -516,7 +632,7 @@ export interface paths {
516
632
  };
517
633
  /**
518
634
  * List Team Members
519
- * @description List all Users that belong to the given Team in the current Account.
635
+ * @description List all Users that belong to the given Team in the current Account. Supports `?expand=user,team,roles` to inline referenced rows.
520
636
  */
521
637
  get: operations["team/listMembers"];
522
638
  put?: never;
@@ -551,6 +667,70 @@ export interface paths {
551
667
  patch?: never;
552
668
  trace?: never;
553
669
  };
670
+ "/team/{team_id}/invite": {
671
+ parameters: {
672
+ query?: never;
673
+ header?: never;
674
+ path?: never;
675
+ cookie?: never;
676
+ };
677
+ /**
678
+ * List pending invites for a Team
679
+ * @description Returns all pending (not consumed, not expired) team invites for the given team. Accepts a FaableQL `query` parameter on the `email` field.
680
+ */
681
+ get: operations["team/listInvites"];
682
+ put?: never;
683
+ /**
684
+ * Invite a user to a Team by email
685
+ * @description Invites a user by email. `mode='auto'` (default) adds the user directly when the email already corresponds to a user in this tenant and falls back to a ticketed invite + email otherwise. `mode='invite'` always issues a ticket + email even when the user exists. Re-inviting the same email to the same team invalidates the previous pending invite.
686
+ */
687
+ post: operations["team/invite"];
688
+ delete?: never;
689
+ options?: never;
690
+ head?: never;
691
+ patch?: never;
692
+ trace?: never;
693
+ };
694
+ "/team/{team_id}/invite/{ticket_id}": {
695
+ parameters: {
696
+ query?: never;
697
+ header?: never;
698
+ path?: never;
699
+ cookie?: never;
700
+ };
701
+ get?: never;
702
+ put?: never;
703
+ post?: never;
704
+ /**
705
+ * Revoke a pending team invite
706
+ * @description Marks a pending team invite as consumed so it can no longer be accepted. Returns 400 if the invite is already consumed and 404 if it does not exist or belongs to a different team.
707
+ */
708
+ delete: operations["team/revokeInvite"];
709
+ options?: never;
710
+ head?: never;
711
+ patch?: never;
712
+ trace?: never;
713
+ };
714
+ "/invite-verify": {
715
+ parameters: {
716
+ query?: never;
717
+ header?: never;
718
+ path?: never;
719
+ cookie?: never;
720
+ };
721
+ /**
722
+ * Verify a team-invite ticket and add the user to the team
723
+ * @description Entry point for the link sent to the invitee. Consumes the ticket, creates the user if needed (with `email_verified=true` — the click proves ownership), and adds them to the team with the invited roles. Then redirects to the `redirect_uri` supplied at invite time with `?status=accepted` appended; falls back to `/flow/team-invite-done` on the auth host when no `redirect_uri` was given. Idempotent if the user is already a member.
724
+ */
725
+ get: operations["team_invite_verify"];
726
+ put?: never;
727
+ post?: never;
728
+ delete?: never;
729
+ options?: never;
730
+ head?: never;
731
+ patch?: never;
732
+ trace?: never;
733
+ };
554
734
  "/api": {
555
735
  parameters: {
556
736
  query?: never;
@@ -1326,7 +1506,21 @@ export interface components {
1326
1506
  * @default false
1327
1507
  */
1328
1508
  welcome_email_enabled: boolean;
1509
+ /**
1510
+ * @description Send a verification email automatically when a user is created with `email_verified=false` and an email address. The link in the email lands on `GET /verify-email?ticket=...` and flips `email_verified=true` with `email_verified_method=verification_flow`. When `false`, verification emails must be requested explicitly via `POST /user/:id/verify-email/start`.
1511
+ * @default false
1512
+ */
1513
+ verify_email_auto_send: boolean;
1329
1514
  };
1515
+ /** @description Policy for the user email-change flow. `new_only` (default) sends a single confirmation link to the new email. `old_and_new` requires the user to also click a link sent to the previous email before the swap takes effect — stricter, useful for tenants with higher-risk users. */
1516
+ email_change_verification_mode?: "new_only" | "old_and_new";
1517
+ /**
1518
+ * @description Controls what happens to `user.email` on subsequent OAuth/federated logins when the user previously changed their email manually through this auth server (i.e. `user.email_change_locked_at` is set).
1519
+ *
1520
+ * - `preserve_manual` (default): the manually-set email wins. The federated provider's email is ignored on re-sync; `email` and `email_verified` are not touched. The identity link stays valid via `provider_user_id`, so the user can still log in with Google/etc.
1521
+ * - `always_sync`: the federated provider's email is always written back, overwriting any manual change. Useful for tenants whose source of truth for identity is the IdP (corporate SSO, etc.).
1522
+ */
1523
+ email_oauth_sync_policy?: "preserve_manual" | "always_sync";
1330
1524
  /** @description AuthAccount creation date */
1331
1525
  createdAt: string;
1332
1526
  /** @description AuthAccount updated date */
@@ -1340,7 +1534,14 @@ export interface components {
1340
1534
  * @default false
1341
1535
  */
1342
1536
  welcome_email_enabled: boolean;
1537
+ /**
1538
+ * @description Send a verification email automatically when a user is created with `email_verified=false` and an email address. The link in the email lands on `GET /verify-email?ticket=...` and flips `email_verified=true` with `email_verified_method=verification_flow`. When `false`, verification emails must be requested explicitly via `POST /user/:id/verify-email/start`.
1539
+ * @default false
1540
+ */
1541
+ verify_email_auto_send: boolean;
1343
1542
  };
1543
+ /** @description Policy for the user email-change flow. `new_only` (default) sends a single confirmation link to the new email. `old_and_new` requires the user to also click a link sent to the previous email before the swap takes effect — stricter, useful for tenants with higher-risk users. */
1544
+ EmailChangeVerificationMode: "new_only" | "old_and_new";
1344
1545
  /** @description Connection */
1345
1546
  Connection: {
1346
1547
  /** @description Connection ID */
@@ -1376,6 +1577,10 @@ export interface components {
1376
1577
  authorize_params: {
1377
1578
  [key: string]: string;
1378
1579
  };
1580
+ /** @description Derived: true when the connection_type has shared Faable defaults AND the tenant has not set its own client_id/client_secret. Read-only — set by the server on every read. */
1581
+ readonly is_using_default_credentials: boolean;
1582
+ /** @description Per-connection override of `Account.email_oauth_sync_policy`. When set on a Connection, takes precedence over the Account-level setting for logins through this IdP. When unset (default), the Account-level policy applies. Use this to allow `always_sync` for a trusted IdP (e.g. corporate SSO) while keeping `preserve_manual` for others within the same tenant. */
1583
+ email_oauth_sync_policy?: "preserve_manual" | "always_sync";
1379
1584
  /** @description Object is related with this account */
1380
1585
  account: string;
1381
1586
  /**
@@ -1419,6 +1624,13 @@ export interface components {
1419
1624
  authorize_params: {
1420
1625
  [key: string]: string;
1421
1626
  };
1627
+ /**
1628
+ * @description Controls what happens to `user.email` on subsequent OAuth/federated logins when the user previously changed their email manually through this auth server (i.e. `user.email_change_locked_at` is set).
1629
+ *
1630
+ * - `preserve_manual` (default): the manually-set email wins. The federated provider's email is ignored on re-sync; `email` and `email_verified` are not touched. The identity link stays valid via `provider_user_id`, so the user can still log in with Google/etc.
1631
+ * - `always_sync`: the federated provider's email is always written back, overwriting any manual change. Useful for tenants whose source of truth for identity is the IdP (corporate SSO, etc.).
1632
+ */
1633
+ email_oauth_sync_policy?: "preserve_manual" | "always_sync";
1422
1634
  /** @description Add Metadata */
1423
1635
  metadata?: {
1424
1636
  [key: string]: unknown;
@@ -1428,6 +1640,29 @@ export interface components {
1428
1640
  ConnectionMetadataCreate: {
1429
1641
  [key: string]: unknown;
1430
1642
  };
1643
+ /** @description Partial update for a Connection. Only the supplied fields are modified. `connection_type` is intentionally excluded — changing it would orphan every identity already linked to this connection. */
1644
+ ConnectionUpdate: {
1645
+ connection_name?: string;
1646
+ enabled?: boolean;
1647
+ enabled_clients?: string[];
1648
+ scope?: string[];
1649
+ client_id?: string;
1650
+ client_secret?: string;
1651
+ issuer?: string;
1652
+ authorize_url?: string;
1653
+ token_url?: string;
1654
+ userinfo_url?: string;
1655
+ jwks_url?: string;
1656
+ response_type?: string;
1657
+ /**
1658
+ * @description Authorize params
1659
+ * @default {}
1660
+ */
1661
+ authorize_params: {
1662
+ [key: string]: string;
1663
+ };
1664
+ email_oauth_sync_policy?: "preserve_manual" | "always_sync" | null;
1665
+ };
1431
1666
  /** @description Client */
1432
1667
  Client: {
1433
1668
  /** @description Client ID */
@@ -1493,6 +1728,36 @@ export interface components {
1493
1728
  ClientMetadataCreate: {
1494
1729
  [key: string]: unknown;
1495
1730
  };
1731
+ /** @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. */
1732
+ ClientUpdate: {
1733
+ /** @description Human-readable client name shown in consent screens. */
1734
+ name?: string;
1735
+ /** @description Free-form description for internal admin use. */
1736
+ description?: string;
1737
+ /** @description Whitelist of allowed OAuth `redirect_uri` values. */
1738
+ callbacks?: string[];
1739
+ /** @description Whitelist of allowed `post_logout_redirect_uri` values. */
1740
+ logout_urls?: string[];
1741
+ refresh_token?: {
1742
+ /** @enum {unknown} */
1743
+ expiration_mode: "expire" | "not-expire";
1744
+ infinite_token_lifetime: boolean;
1745
+ token_lifetime: number;
1746
+ };
1747
+ client_uri?: string | null;
1748
+ logo_uri?: string | null;
1749
+ tos_uri?: string | null;
1750
+ policy_uri?: string | null;
1751
+ contacts?: string[];
1752
+ grant_types?: string[];
1753
+ response_types?: string[];
1754
+ token_endpoint_auth_method?: string;
1755
+ application_type?: string;
1756
+ software_id?: string | null;
1757
+ software_version?: string | null;
1758
+ frontchannel_logout_uri?: string | null;
1759
+ frontchannel_logout_session_required?: boolean;
1760
+ };
1496
1761
  /** @description User */
1497
1762
  User: {
1498
1763
  /** @description User ID */
@@ -1516,10 +1781,20 @@ export interface components {
1516
1781
  * @default false
1517
1782
  */
1518
1783
  email_verified: boolean;
1784
+ /** @description How `email_verified` was last set. `manual` — admin flipped the flag via `POST /user/:id`. `verification_flow` — user clicked the verification link. `passwordless_otp` — user completed passwordless OTP login. `team_invite` — user clicked a team invitation link. `email_change` — user confirmed a self-service email change. `federated` — verified by the external IdP on OAuth callback. `null` — the field was cleared (admin un-verified the email). */
1785
+ email_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | null;
1786
+ /** @description ISO 8601 timestamp of when `email_verified` was last flipped to true. */
1787
+ email_verified_at?: string | null;
1788
+ /** @description ISO 8601 timestamp of the user's last verified email change. When set, OAuth callbacks will not overwrite `email`/`email_verified` from the federated provider — the manually-chosen email wins. */
1789
+ email_change_locked_at?: string | null;
1519
1790
  /** @description contact phone number */
1520
1791
  phone?: string | null;
1521
1792
  /** @description phone is verified */
1522
1793
  phone_verified: boolean;
1794
+ /** @description How `phone_verified` was last set. Same enum as `email_verified_method`. */
1795
+ phone_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | null;
1796
+ /** @description ISO 8601 timestamp of when `phone_verified` was last flipped to true. */
1797
+ phone_verified_at?: string | null;
1523
1798
  /** @description country iso code */
1524
1799
  country_iso?: string | null;
1525
1800
  /** @description user birth_date */
@@ -1660,12 +1935,16 @@ export interface components {
1660
1935
  given_name?: string;
1661
1936
  /** @description family name */
1662
1937
  family_name?: string;
1663
- /** @description contact email */
1938
+ /** @description Contact email. Changing the email to a new value automatically resets `email_verified` to false (and clears `email_verified_method` / `email_verified_at`) unless the same patch sets `email_verified` explicitly. The override is the documented way to import a pre-verified user from another IdP. */
1664
1939
  email?: string;
1940
+ /** @description Flip the email verification flag. Setting `true` marks the email as verified by the admin (`email_verified_method=manual`). Setting `false` clears the verification metadata. */
1941
+ email_verified?: boolean;
1665
1942
  /** @description New password for this user */
1666
1943
  password?: string;
1667
- /** @description contact phone number */
1944
+ /** @description Contact phone number. Changing it to a new value automatically resets `phone_verified` to false (and clears `phone_verified_method` / `phone_verified_at`) unless the same patch sets `phone_verified` explicitly. */
1668
1945
  phone?: string;
1946
+ /** @description Flip the phone verification flag. Setting `true` marks the phone as verified by the admin (`phone_verified_method=manual`). */
1947
+ phone_verified?: boolean;
1669
1948
  /** @description user country as iso string */
1670
1949
  country_iso?: string;
1671
1950
  /** @description user birth_date */
@@ -1783,6 +2062,13 @@ export interface components {
1783
2062
  RoleMetadataCreate: {
1784
2063
  [key: string]: unknown;
1785
2064
  };
2065
+ /** @description Partial update for a Role. Only the supplied fields are modified. */
2066
+ RoleUpdate: {
2067
+ /** @description New human-readable identifier for the role. */
2068
+ name?: string;
2069
+ /** @description New free-form description of what users in this role do. */
2070
+ description?: string;
2071
+ };
1786
2072
  /** @description RoleMember */
1787
2073
  RoleMember: {
1788
2074
  /** @description RoleMember ID */
@@ -1879,6 +2165,21 @@ export interface components {
1879
2165
  TeamMetadataCreate: {
1880
2166
  [key: string]: unknown;
1881
2167
  };
2168
+ /** @description Partial update for a Team. Only the supplied fields are modified. `slug` is auto-derived from `name` and is not user-editable. */
2169
+ TeamUpdate: {
2170
+ /** @description New human-readable name for the team. */
2171
+ name?: string;
2172
+ /** @description New free-form description for the team. */
2173
+ description?: string;
2174
+ /** @description Arbitrary key/value pairs attached to the team. Replaces the previous metadata entirely. */
2175
+ metadata?: {
2176
+ [key: string]: unknown;
2177
+ };
2178
+ };
2179
+ /** @description Arbitrary key/value pairs attached to the team. Replaces the previous metadata entirely. */
2180
+ TeamUpdateMetadata: {
2181
+ [key: string]: unknown;
2182
+ };
1882
2183
  /** @description TeamMember */
1883
2184
  TeamMember: {
1884
2185
  /** @description TeamMember ID */
@@ -1919,6 +2220,14 @@ export interface components {
1919
2220
  * ]
1920
2221
  */
1921
2222
  users: string[];
2223
+ /**
2224
+ * @description Role ids to grant to the added members within the scope of this team.
2225
+ * @default []
2226
+ * @example [
2227
+ * "role_6555fd293acc2f0fac0e3452"
2228
+ * ]
2229
+ */
2230
+ roles: string[];
1922
2231
  };
1923
2232
  /** @description A permission exposed by an API: a single value that may end up in the `permissions` claim of an access_token, plus a human-readable description shown in the consent prompt. */
1924
2233
  Permission: {
@@ -2397,6 +2706,17 @@ export interface components {
2397
2706
  message?: string;
2398
2707
  /** @description Type-specific structured payload */
2399
2708
  data?: unknown;
2709
+ user?: components["schemas"]["User"] | string | unknown;
2710
+ client?: components["schemas"]["Client"] | string | unknown;
2711
+ connection?: components["schemas"]["Connection"] | string | unknown;
2712
+ team?: components["schemas"]["Team"] | string | unknown;
2713
+ identity?: components["schemas"]["Identity"] | string | unknown;
2714
+ ticket?: string;
2715
+ /**
2716
+ * Format: date-time
2717
+ * @description When this log row will be auto-deleted by the Mongo TTL monitor. Absent on rows recorded without `ttl_seconds`.
2718
+ */
2719
+ expires_at?: string;
2400
2720
  /** @description Object is related with this account */
2401
2721
  account: string;
2402
2722
  /**
@@ -2552,6 +2872,18 @@ export interface components {
2552
2872
  callback_hostnames?: string[];
2553
2873
  default_connection?: string | null;
2554
2874
  enabled_locales?: string[];
2875
+ notification_settings?: {
2876
+ /**
2877
+ * @description Send the built-in welcome email on user.created
2878
+ * @default false
2879
+ */
2880
+ welcome_email_enabled: boolean;
2881
+ /**
2882
+ * @description Send a verification email automatically when a user is created with `email_verified=false` and an email address. The link in the email lands on `GET /verify-email?ticket=...` and flips `email_verified=true` with `email_verified_method=verification_flow`. When `false`, verification emails must be requested explicitly via `POST /user/:id/verify-email/start`.
2883
+ * @default false
2884
+ */
2885
+ verify_email_auto_send: boolean;
2886
+ };
2555
2887
  };
2556
2888
  OAuthTokenParams: {
2557
2889
  /** @description Grant Type. https://oauth.net/2/grant-types/ */
@@ -2655,7 +2987,21 @@ export interface operations {
2655
2987
  * @default false
2656
2988
  */
2657
2989
  welcome_email_enabled: boolean;
2990
+ /**
2991
+ * @description Send a verification email automatically when a user is created with `email_verified=false` and an email address. The link in the email lands on `GET /verify-email?ticket=...` and flips `email_verified=true` with `email_verified_method=verification_flow`. When `false`, verification emails must be requested explicitly via `POST /user/:id/verify-email/start`.
2992
+ * @default false
2993
+ */
2994
+ verify_email_auto_send: boolean;
2658
2995
  };
2996
+ /** @description Policy for the user email-change flow. `new_only` (default) sends a single confirmation link to the new email. `old_and_new` requires the user to also click a link sent to the previous email before the swap takes effect — stricter, useful for tenants with higher-risk users. */
2997
+ email_change_verification_mode?: "new_only" | "old_and_new";
2998
+ /**
2999
+ * @description Controls what happens to `user.email` on subsequent OAuth/federated logins when the user previously changed their email manually through this auth server (i.e. `user.email_change_locked_at` is set).
3000
+ *
3001
+ * - `preserve_manual` (default): the manually-set email wins. The federated provider's email is ignored on re-sync; `email` and `email_verified` are not touched. The identity link stays valid via `provider_user_id`, so the user can still log in with Google/etc.
3002
+ * - `always_sync`: the federated provider's email is always written back, overwriting any manual change. Useful for tenants whose source of truth for identity is the IdP (corporate SSO, etc.).
3003
+ */
3004
+ email_oauth_sync_policy?: "preserve_manual" | "always_sync";
2659
3005
  /** @description AuthAccount creation date */
2660
3006
  createdAt: string;
2661
3007
  /** @description AuthAccount updated date */
@@ -2752,7 +3098,21 @@ export interface operations {
2752
3098
  * @default false
2753
3099
  */
2754
3100
  welcome_email_enabled: boolean;
3101
+ /**
3102
+ * @description Send a verification email automatically when a user is created with `email_verified=false` and an email address. The link in the email lands on `GET /verify-email?ticket=...` and flips `email_verified=true` with `email_verified_method=verification_flow`. When `false`, verification emails must be requested explicitly via `POST /user/:id/verify-email/start`.
3103
+ * @default false
3104
+ */
3105
+ verify_email_auto_send: boolean;
2755
3106
  };
3107
+ /** @description Policy for the user email-change flow. `new_only` (default) sends a single confirmation link to the new email. `old_and_new` requires the user to also click a link sent to the previous email before the swap takes effect — stricter, useful for tenants with higher-risk users. */
3108
+ email_change_verification_mode?: "new_only" | "old_and_new";
3109
+ /**
3110
+ * @description Controls what happens to `user.email` on subsequent OAuth/federated logins when the user previously changed their email manually through this auth server (i.e. `user.email_change_locked_at` is set).
3111
+ *
3112
+ * - `preserve_manual` (default): the manually-set email wins. The federated provider's email is ignored on re-sync; `email` and `email_verified` are not touched. The identity link stays valid via `provider_user_id`, so the user can still log in with Google/etc.
3113
+ * - `always_sync`: the federated provider's email is always written back, overwriting any manual change. Useful for tenants whose source of truth for identity is the IdP (corporate SSO, etc.).
3114
+ */
3115
+ email_oauth_sync_policy?: "preserve_manual" | "always_sync";
2756
3116
  /** @description AuthAccount creation date */
2757
3117
  createdAt: string;
2758
3118
  /** @description AuthAccount updated date */
@@ -2804,7 +3164,21 @@ export interface operations {
2804
3164
  * @default false
2805
3165
  */
2806
3166
  welcome_email_enabled: boolean;
3167
+ /**
3168
+ * @description Send a verification email automatically when a user is created with `email_verified=false` and an email address. The link in the email lands on `GET /verify-email?ticket=...` and flips `email_verified=true` with `email_verified_method=verification_flow`. When `false`, verification emails must be requested explicitly via `POST /user/:id/verify-email/start`.
3169
+ * @default false
3170
+ */
3171
+ verify_email_auto_send: boolean;
2807
3172
  };
3173
+ /** @description Policy for the user email-change flow. `new_only` (default) sends a single confirmation link to the new email. `old_and_new` requires the user to also click a link sent to the previous email before the swap takes effect — stricter, useful for tenants with higher-risk users. */
3174
+ email_change_verification_mode?: "new_only" | "old_and_new";
3175
+ /**
3176
+ * @description Controls what happens to `user.email` on subsequent OAuth/federated logins when the user previously changed their email manually through this auth server (i.e. `user.email_change_locked_at` is set).
3177
+ *
3178
+ * - `preserve_manual` (default): the manually-set email wins. The federated provider's email is ignored on re-sync; `email` and `email_verified` are not touched. The identity link stays valid via `provider_user_id`, so the user can still log in with Google/etc.
3179
+ * - `always_sync`: the federated provider's email is always written back, overwriting any manual change. Useful for tenants whose source of truth for identity is the IdP (corporate SSO, etc.).
3180
+ */
3181
+ email_oauth_sync_policy?: "preserve_manual" | "always_sync";
2808
3182
  /** @description AuthAccount creation date */
2809
3183
  createdAt: string;
2810
3184
  /** @description AuthAccount updated date */
@@ -2832,6 +3206,18 @@ export interface operations {
2832
3206
  callback_hostnames?: string[];
2833
3207
  default_connection?: string | null;
2834
3208
  enabled_locales?: string[];
3209
+ notification_settings?: {
3210
+ /**
3211
+ * @description Send the built-in welcome email on user.created
3212
+ * @default false
3213
+ */
3214
+ welcome_email_enabled?: boolean;
3215
+ /**
3216
+ * @description Send a verification email automatically when a user is created with `email_verified=false` and an email address. The link in the email lands on `GET /verify-email?ticket=...` and flips `email_verified=true` with `email_verified_method=verification_flow`. When `false`, verification emails must be requested explicitly via `POST /user/:id/verify-email/start`.
3217
+ * @default false
3218
+ */
3219
+ verify_email_auto_send?: boolean;
3220
+ };
2835
3221
  };
2836
3222
  };
2837
3223
  };
@@ -2864,7 +3250,21 @@ export interface operations {
2864
3250
  * @default false
2865
3251
  */
2866
3252
  welcome_email_enabled: boolean;
3253
+ /**
3254
+ * @description Send a verification email automatically when a user is created with `email_verified=false` and an email address. The link in the email lands on `GET /verify-email?ticket=...` and flips `email_verified=true` with `email_verified_method=verification_flow`. When `false`, verification emails must be requested explicitly via `POST /user/:id/verify-email/start`.
3255
+ * @default false
3256
+ */
3257
+ verify_email_auto_send: boolean;
2867
3258
  };
3259
+ /** @description Policy for the user email-change flow. `new_only` (default) sends a single confirmation link to the new email. `old_and_new` requires the user to also click a link sent to the previous email before the swap takes effect — stricter, useful for tenants with higher-risk users. */
3260
+ email_change_verification_mode?: "new_only" | "old_and_new";
3261
+ /**
3262
+ * @description Controls what happens to `user.email` on subsequent OAuth/federated logins when the user previously changed their email manually through this auth server (i.e. `user.email_change_locked_at` is set).
3263
+ *
3264
+ * - `preserve_manual` (default): the manually-set email wins. The federated provider's email is ignored on re-sync; `email` and `email_verified` are not touched. The identity link stays valid via `provider_user_id`, so the user can still log in with Google/etc.
3265
+ * - `always_sync`: the federated provider's email is always written back, overwriting any manual change. Useful for tenants whose source of truth for identity is the IdP (corporate SSO, etc.).
3266
+ */
3267
+ email_oauth_sync_policy?: "preserve_manual" | "always_sync";
2868
3268
  /** @description AuthAccount creation date */
2869
3269
  createdAt: string;
2870
3270
  /** @description AuthAccount updated date */
@@ -2925,7 +3325,21 @@ export interface operations {
2925
3325
  * @default false
2926
3326
  */
2927
3327
  welcome_email_enabled: boolean;
3328
+ /**
3329
+ * @description Send a verification email automatically when a user is created with `email_verified=false` and an email address. The link in the email lands on `GET /verify-email?ticket=...` and flips `email_verified=true` with `email_verified_method=verification_flow`. When `false`, verification emails must be requested explicitly via `POST /user/:id/verify-email/start`.
3330
+ * @default false
3331
+ */
3332
+ verify_email_auto_send: boolean;
2928
3333
  };
3334
+ /** @description Policy for the user email-change flow. `new_only` (default) sends a single confirmation link to the new email. `old_and_new` requires the user to also click a link sent to the previous email before the swap takes effect — stricter, useful for tenants with higher-risk users. */
3335
+ email_change_verification_mode?: "new_only" | "old_and_new";
3336
+ /**
3337
+ * @description Controls what happens to `user.email` on subsequent OAuth/federated logins when the user previously changed their email manually through this auth server (i.e. `user.email_change_locked_at` is set).
3338
+ *
3339
+ * - `preserve_manual` (default): the manually-set email wins. The federated provider's email is ignored on re-sync; `email` and `email_verified` are not touched. The identity link stays valid via `provider_user_id`, so the user can still log in with Google/etc.
3340
+ * - `always_sync`: the federated provider's email is always written back, overwriting any manual change. Useful for tenants whose source of truth for identity is the IdP (corporate SSO, etc.).
3341
+ */
3342
+ email_oauth_sync_policy?: "preserve_manual" | "always_sync";
2929
3343
  /** @description AuthAccount creation date */
2930
3344
  createdAt: string;
2931
3345
  /** @description AuthAccount updated date */
@@ -2946,6 +3360,8 @@ export interface operations {
2946
3360
  pageSize?: number;
2947
3361
  /** @description Filter using a FaableQL query */
2948
3362
  query?: string;
3363
+ /** @description Full-text search across: `connection_name`, `connection_type`. */
3364
+ q?: string;
2949
3365
  };
2950
3366
  header?: never;
2951
3367
  path?: never;
@@ -3000,6 +3416,13 @@ export interface operations {
3000
3416
  authorize_params?: {
3001
3417
  [key: string]: string;
3002
3418
  };
3419
+ /**
3420
+ * @description Controls what happens to `user.email` on subsequent OAuth/federated logins when the user previously changed their email manually through this auth server (i.e. `user.email_change_locked_at` is set).
3421
+ *
3422
+ * - `preserve_manual` (default): the manually-set email wins. The federated provider's email is ignored on re-sync; `email` and `email_verified` are not touched. The identity link stays valid via `provider_user_id`, so the user can still log in with Google/etc.
3423
+ * - `always_sync`: the federated provider's email is always written back, overwriting any manual change. Useful for tenants whose source of truth for identity is the IdP (corporate SSO, etc.).
3424
+ */
3425
+ email_oauth_sync_policy?: "preserve_manual" | "always_sync";
3003
3426
  /** @description Add Metadata */
3004
3427
  metadata?: {
3005
3428
  [key: string]: unknown;
@@ -3048,6 +3471,10 @@ export interface operations {
3048
3471
  authorize_params: {
3049
3472
  [key: string]: string;
3050
3473
  };
3474
+ /** @description Derived: true when the connection_type has shared Faable defaults AND the tenant has not set its own client_id/client_secret. Read-only — set by the server on every read. */
3475
+ readonly is_using_default_credentials: boolean;
3476
+ /** @description Per-connection override of `Account.email_oauth_sync_policy`. When set on a Connection, takes precedence over the Account-level setting for logins through this IdP. When unset (default), the Account-level policy applies. Use this to allow `always_sync` for a trusted IdP (e.g. corporate SSO) while keeping `preserve_manual` for others within the same tenant. */
3477
+ email_oauth_sync_policy?: "preserve_manual" | "always_sync";
3051
3478
  /** @description Object is related with this account */
3052
3479
  account: string;
3053
3480
  /**
@@ -3117,6 +3544,10 @@ export interface operations {
3117
3544
  authorize_params: {
3118
3545
  [key: string]: string;
3119
3546
  };
3547
+ /** @description Derived: true when the connection_type has shared Faable defaults AND the tenant has not set its own client_id/client_secret. Read-only — set by the server on every read. */
3548
+ readonly is_using_default_credentials: boolean;
3549
+ /** @description Per-connection override of `Account.email_oauth_sync_policy`. When set on a Connection, takes precedence over the Account-level setting for logins through this IdP. When unset (default), the Account-level policy applies. Use this to allow `always_sync` for a trusted IdP (e.g. corporate SSO) while keeping `preserve_manual` for others within the same tenant. */
3550
+ email_oauth_sync_policy?: "preserve_manual" | "always_sync";
3120
3551
  /** @description Object is related with this account */
3121
3552
  account: string;
3122
3553
  /**
@@ -3135,7 +3566,7 @@ export interface operations {
3135
3566
  };
3136
3567
  };
3137
3568
  };
3138
- "connection/remove": {
3569
+ "connection/update": {
3139
3570
  parameters: {
3140
3571
  query?: never;
3141
3572
  header?: never;
@@ -3144,9 +3575,108 @@ export interface operations {
3144
3575
  };
3145
3576
  cookie?: never;
3146
3577
  };
3147
- requestBody?: never;
3148
- responses: {
3149
- /** @description Default Response */
3578
+ /** @description Partial update for a Connection. Only the supplied fields are modified. `connection_type` is intentionally excluded — changing it would orphan every identity already linked to this connection. */
3579
+ requestBody: {
3580
+ content: {
3581
+ "application/json": {
3582
+ connection_name?: string;
3583
+ enabled?: boolean;
3584
+ enabled_clients?: string[];
3585
+ scope?: string[];
3586
+ client_id?: string;
3587
+ client_secret?: string;
3588
+ issuer?: string;
3589
+ authorize_url?: string;
3590
+ token_url?: string;
3591
+ userinfo_url?: string;
3592
+ jwks_url?: string;
3593
+ response_type?: string;
3594
+ /**
3595
+ * @description Authorize params
3596
+ * @default {}
3597
+ */
3598
+ authorize_params?: {
3599
+ [key: string]: string;
3600
+ };
3601
+ email_oauth_sync_policy?: "preserve_manual" | "always_sync" | null;
3602
+ };
3603
+ };
3604
+ };
3605
+ responses: {
3606
+ /** @description Connection */
3607
+ 200: {
3608
+ headers: {
3609
+ [name: string]: unknown;
3610
+ };
3611
+ content: {
3612
+ "application/json": {
3613
+ /** @description Connection ID */
3614
+ id: string;
3615
+ connection_name: string;
3616
+ /** @enum {unknown} */
3617
+ connection_type: "database" | "custom" | "github" | "figma" | "google_oauth2" | "oidc" | "passwordless_email";
3618
+ /** @default null */
3619
+ authorize_url: string;
3620
+ /** @default null */
3621
+ token_url: string;
3622
+ /** @default null */
3623
+ userinfo_url: string;
3624
+ /** @default null */
3625
+ client_id: string;
3626
+ /** @default null */
3627
+ client_secret: string;
3628
+ /** @default null */
3629
+ issuer: string;
3630
+ /** @default null */
3631
+ jwks_url: string;
3632
+ /** @default null */
3633
+ response_type: string;
3634
+ enabled: boolean;
3635
+ /** @default null */
3636
+ enabled_clients: string[] | null;
3637
+ /** @default [] */
3638
+ scope: string[];
3639
+ /**
3640
+ * @description Authorize params
3641
+ * @default {}
3642
+ */
3643
+ authorize_params: {
3644
+ [key: string]: string;
3645
+ };
3646
+ /** @description Derived: true when the connection_type has shared Faable defaults AND the tenant has not set its own client_id/client_secret. Read-only — set by the server on every read. */
3647
+ readonly is_using_default_credentials: boolean;
3648
+ /** @description Per-connection override of `Account.email_oauth_sync_policy`. When set on a Connection, takes precedence over the Account-level setting for logins through this IdP. When unset (default), the Account-level policy applies. Use this to allow `always_sync` for a trusted IdP (e.g. corporate SSO) while keeping `preserve_manual` for others within the same tenant. */
3649
+ email_oauth_sync_policy?: "preserve_manual" | "always_sync";
3650
+ /** @description Object is related with this account */
3651
+ account: string;
3652
+ /**
3653
+ * @description ConnectionMetadata
3654
+ * @default {}
3655
+ */
3656
+ metadata: {
3657
+ [key: string]: unknown;
3658
+ };
3659
+ /** @description Connection creation date */
3660
+ createdAt: string;
3661
+ /** @description Connection updated date */
3662
+ updatedAt?: string;
3663
+ };
3664
+ };
3665
+ };
3666
+ };
3667
+ };
3668
+ "connection/remove": {
3669
+ parameters: {
3670
+ query?: never;
3671
+ header?: never;
3672
+ path: {
3673
+ connection_id: string;
3674
+ };
3675
+ cookie?: never;
3676
+ };
3677
+ requestBody?: never;
3678
+ responses: {
3679
+ /** @description Default Response */
3150
3680
  200: {
3151
3681
  headers: {
3152
3682
  [name: string]: unknown;
@@ -3166,6 +3696,8 @@ export interface operations {
3166
3696
  pageSize?: number;
3167
3697
  /** @description Filter using a FaableQL query */
3168
3698
  query?: string;
3699
+ /** @description Full-text search across: `name`, `description`, `client_id`. */
3700
+ q?: string;
3169
3701
  };
3170
3702
  header?: never;
3171
3703
  path?: never;
@@ -3327,6 +3859,102 @@ export interface operations {
3327
3859
  };
3328
3860
  };
3329
3861
  };
3862
+ "client/update": {
3863
+ parameters: {
3864
+ query?: never;
3865
+ header?: never;
3866
+ path: {
3867
+ client_id: string;
3868
+ };
3869
+ cookie?: never;
3870
+ };
3871
+ /** @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. */
3872
+ requestBody: {
3873
+ content: {
3874
+ "application/json": {
3875
+ /** @description Human-readable client name shown in consent screens. */
3876
+ name?: string;
3877
+ /** @description Free-form description for internal admin use. */
3878
+ description?: string;
3879
+ /** @description Whitelist of allowed OAuth `redirect_uri` values. */
3880
+ callbacks?: string[];
3881
+ /** @description Whitelist of allowed `post_logout_redirect_uri` values. */
3882
+ logout_urls?: string[];
3883
+ refresh_token?: {
3884
+ /** @enum {unknown} */
3885
+ expiration_mode: "expire" | "not-expire";
3886
+ infinite_token_lifetime: boolean;
3887
+ token_lifetime: number;
3888
+ };
3889
+ client_uri?: string | null;
3890
+ logo_uri?: string | null;
3891
+ tos_uri?: string | null;
3892
+ policy_uri?: string | null;
3893
+ contacts?: string[];
3894
+ grant_types?: string[];
3895
+ response_types?: string[];
3896
+ token_endpoint_auth_method?: string;
3897
+ application_type?: string;
3898
+ software_id?: string | null;
3899
+ software_version?: string | null;
3900
+ frontchannel_logout_uri?: string | null;
3901
+ frontchannel_logout_session_required?: boolean;
3902
+ };
3903
+ };
3904
+ };
3905
+ responses: {
3906
+ /** @description Client */
3907
+ 200: {
3908
+ headers: {
3909
+ [name: string]: unknown;
3910
+ };
3911
+ content: {
3912
+ "application/json": {
3913
+ /** @description Client ID */
3914
+ id: string;
3915
+ name: string;
3916
+ description: string;
3917
+ client_id: string;
3918
+ client_secret: string;
3919
+ callbacks: string[];
3920
+ logout_urls: string[];
3921
+ refresh_token: {
3922
+ /** @enum {unknown} */
3923
+ expiration_mode: "expire" | "not-expire";
3924
+ infinite_token_lifetime: boolean;
3925
+ token_lifetime: number;
3926
+ };
3927
+ client_uri?: string | null;
3928
+ logo_uri?: string | null;
3929
+ tos_uri?: string | null;
3930
+ policy_uri?: string | null;
3931
+ contacts?: string[];
3932
+ grant_types?: string[];
3933
+ response_types?: string[];
3934
+ token_endpoint_auth_method?: string;
3935
+ application_type?: string;
3936
+ software_id?: string | null;
3937
+ software_version?: string | null;
3938
+ frontchannel_logout_uri?: string | null;
3939
+ frontchannel_logout_session_required?: boolean;
3940
+ /** @description Object is related with this account */
3941
+ account: string;
3942
+ /**
3943
+ * @description ClientMetadata
3944
+ * @default {}
3945
+ */
3946
+ metadata: {
3947
+ [key: string]: unknown;
3948
+ };
3949
+ /** @description Client creation date */
3950
+ createdAt: string;
3951
+ /** @description Client updated date */
3952
+ updatedAt?: string;
3953
+ };
3954
+ };
3955
+ };
3956
+ };
3957
+ };
3330
3958
  "client/remove": {
3331
3959
  parameters: {
3332
3960
  query?: never;
@@ -3347,6 +3975,69 @@ export interface operations {
3347
3975
  };
3348
3976
  };
3349
3977
  };
3978
+ "client/rotateSecret": {
3979
+ parameters: {
3980
+ query?: never;
3981
+ header?: never;
3982
+ path: {
3983
+ client_id: string;
3984
+ };
3985
+ cookie?: never;
3986
+ };
3987
+ requestBody?: never;
3988
+ responses: {
3989
+ /** @description Client */
3990
+ 200: {
3991
+ headers: {
3992
+ [name: string]: unknown;
3993
+ };
3994
+ content: {
3995
+ "application/json": {
3996
+ /** @description Client ID */
3997
+ id: string;
3998
+ name: string;
3999
+ description: string;
4000
+ client_id: string;
4001
+ client_secret: string;
4002
+ callbacks: string[];
4003
+ logout_urls: string[];
4004
+ refresh_token: {
4005
+ /** @enum {unknown} */
4006
+ expiration_mode: "expire" | "not-expire";
4007
+ infinite_token_lifetime: boolean;
4008
+ token_lifetime: number;
4009
+ };
4010
+ client_uri?: string | null;
4011
+ logo_uri?: string | null;
4012
+ tos_uri?: string | null;
4013
+ policy_uri?: string | null;
4014
+ contacts?: string[];
4015
+ grant_types?: string[];
4016
+ response_types?: string[];
4017
+ token_endpoint_auth_method?: string;
4018
+ application_type?: string;
4019
+ software_id?: string | null;
4020
+ software_version?: string | null;
4021
+ frontchannel_logout_uri?: string | null;
4022
+ frontchannel_logout_session_required?: boolean;
4023
+ /** @description Object is related with this account */
4024
+ account: string;
4025
+ /**
4026
+ * @description ClientMetadata
4027
+ * @default {}
4028
+ */
4029
+ metadata: {
4030
+ [key: string]: unknown;
4031
+ };
4032
+ /** @description Client creation date */
4033
+ createdAt: string;
4034
+ /** @description Client updated date */
4035
+ updatedAt?: string;
4036
+ };
4037
+ };
4038
+ };
4039
+ };
4040
+ };
3350
4041
  "user/list": {
3351
4042
  parameters: {
3352
4043
  query?: {
@@ -3358,6 +4049,8 @@ export interface operations {
3358
4049
  pageSize?: number;
3359
4050
  /** @description Filter using a FaableQL query */
3360
4051
  query?: string;
4052
+ /** @description Full-text search across: `name`, `email`, `phone`. */
4053
+ q?: string;
3361
4054
  };
3362
4055
  header?: never;
3363
4056
  path?: never;
@@ -3450,10 +4143,20 @@ export interface operations {
3450
4143
  * @default false
3451
4144
  */
3452
4145
  email_verified: boolean;
4146
+ /** @description How `email_verified` was last set. `manual` — admin flipped the flag via `POST /user/:id`. `verification_flow` — user clicked the verification link. `passwordless_otp` — user completed passwordless OTP login. `team_invite` — user clicked a team invitation link. `email_change` — user confirmed a self-service email change. `federated` — verified by the external IdP on OAuth callback. `null` — the field was cleared (admin un-verified the email). */
4147
+ email_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | null;
4148
+ /** @description ISO 8601 timestamp of when `email_verified` was last flipped to true. */
4149
+ email_verified_at?: string | null;
4150
+ /** @description ISO 8601 timestamp of the user's last verified email change. When set, OAuth callbacks will not overwrite `email`/`email_verified` from the federated provider — the manually-chosen email wins. */
4151
+ email_change_locked_at?: string | null;
3453
4152
  /** @description contact phone number */
3454
4153
  phone?: string | null;
3455
4154
  /** @description phone is verified */
3456
4155
  phone_verified: boolean;
4156
+ /** @description How `phone_verified` was last set. Same enum as `email_verified_method`. */
4157
+ phone_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | null;
4158
+ /** @description ISO 8601 timestamp of when `phone_verified` was last flipped to true. */
4159
+ phone_verified_at?: string | null;
3457
4160
  /** @description country iso code */
3458
4161
  country_iso?: string | null;
3459
4162
  /** @description user birth_date */
@@ -3559,10 +4262,20 @@ export interface operations {
3559
4262
  * @default false
3560
4263
  */
3561
4264
  email_verified: boolean;
4265
+ /** @description How `email_verified` was last set. `manual` — admin flipped the flag via `POST /user/:id`. `verification_flow` — user clicked the verification link. `passwordless_otp` — user completed passwordless OTP login. `team_invite` — user clicked a team invitation link. `email_change` — user confirmed a self-service email change. `federated` — verified by the external IdP on OAuth callback. `null` — the field was cleared (admin un-verified the email). */
4266
+ email_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | null;
4267
+ /** @description ISO 8601 timestamp of when `email_verified` was last flipped to true. */
4268
+ email_verified_at?: string | null;
4269
+ /** @description ISO 8601 timestamp of the user's last verified email change. When set, OAuth callbacks will not overwrite `email`/`email_verified` from the federated provider — the manually-chosen email wins. */
4270
+ email_change_locked_at?: string | null;
3562
4271
  /** @description contact phone number */
3563
4272
  phone?: string | null;
3564
4273
  /** @description phone is verified */
3565
4274
  phone_verified: boolean;
4275
+ /** @description How `phone_verified` was last set. Same enum as `email_verified_method`. */
4276
+ phone_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | null;
4277
+ /** @description ISO 8601 timestamp of when `phone_verified` was last flipped to true. */
4278
+ phone_verified_at?: string | null;
3566
4279
  /** @description country iso code */
3567
4280
  country_iso?: string | null;
3568
4281
  /** @description user birth_date */
@@ -3648,12 +4361,16 @@ export interface operations {
3648
4361
  given_name?: string;
3649
4362
  /** @description family name */
3650
4363
  family_name?: string;
3651
- /** @description contact email */
4364
+ /** @description Contact email. Changing the email to a new value automatically resets `email_verified` to false (and clears `email_verified_method` / `email_verified_at`) unless the same patch sets `email_verified` explicitly. The override is the documented way to import a pre-verified user from another IdP. */
3652
4365
  email?: string;
4366
+ /** @description Flip the email verification flag. Setting `true` marks the email as verified by the admin (`email_verified_method=manual`). Setting `false` clears the verification metadata. */
4367
+ email_verified?: boolean;
3653
4368
  /** @description New password for this user */
3654
4369
  password?: string;
3655
- /** @description contact phone number */
4370
+ /** @description Contact phone number. Changing it to a new value automatically resets `phone_verified` to false (and clears `phone_verified_method` / `phone_verified_at`) unless the same patch sets `phone_verified` explicitly. */
3656
4371
  phone?: string;
4372
+ /** @description Flip the phone verification flag. Setting `true` marks the phone as verified by the admin (`phone_verified_method=manual`). */
4373
+ phone_verified?: boolean;
3657
4374
  /** @description user country as iso string */
3658
4375
  country_iso?: string;
3659
4376
  /** @description user birth_date */
@@ -3702,10 +4419,20 @@ export interface operations {
3702
4419
  * @default false
3703
4420
  */
3704
4421
  email_verified: boolean;
4422
+ /** @description How `email_verified` was last set. `manual` — admin flipped the flag via `POST /user/:id`. `verification_flow` — user clicked the verification link. `passwordless_otp` — user completed passwordless OTP login. `team_invite` — user clicked a team invitation link. `email_change` — user confirmed a self-service email change. `federated` — verified by the external IdP on OAuth callback. `null` — the field was cleared (admin un-verified the email). */
4423
+ email_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | null;
4424
+ /** @description ISO 8601 timestamp of when `email_verified` was last flipped to true. */
4425
+ email_verified_at?: string | null;
4426
+ /** @description ISO 8601 timestamp of the user's last verified email change. When set, OAuth callbacks will not overwrite `email`/`email_verified` from the federated provider — the manually-chosen email wins. */
4427
+ email_change_locked_at?: string | null;
3705
4428
  /** @description contact phone number */
3706
4429
  phone?: string | null;
3707
4430
  /** @description phone is verified */
3708
4431
  phone_verified: boolean;
4432
+ /** @description How `phone_verified` was last set. Same enum as `email_verified_method`. */
4433
+ phone_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | null;
4434
+ /** @description ISO 8601 timestamp of when `phone_verified` was last flipped to true. */
4435
+ phone_verified_at?: string | null;
3709
4436
  /** @description country iso code */
3710
4437
  country_iso?: string | null;
3711
4438
  /** @description user birth_date */
@@ -3772,13 +4499,125 @@ export interface operations {
3772
4499
  };
3773
4500
  };
3774
4501
  };
3775
- "user/remove": {
4502
+ "user/remove": {
4503
+ parameters: {
4504
+ query?: never;
4505
+ header?: never;
4506
+ path: {
4507
+ user_id: string;
4508
+ };
4509
+ cookie?: never;
4510
+ };
4511
+ requestBody?: never;
4512
+ responses: {
4513
+ /** @description Default Response */
4514
+ 200: {
4515
+ headers: {
4516
+ [name: string]: unknown;
4517
+ };
4518
+ content?: never;
4519
+ };
4520
+ };
4521
+ };
4522
+ "user/changeEmail": {
4523
+ parameters: {
4524
+ query?: never;
4525
+ header?: never;
4526
+ path: {
4527
+ user_id: string;
4528
+ };
4529
+ cookie?: never;
4530
+ };
4531
+ /** @description Payload for `POST /user/:user_id/change-email`. Triggers the verification flow: a Ticket is created and an email is sent to the new address with a confirmation link. */
4532
+ requestBody: {
4533
+ content: {
4534
+ "application/json": {
4535
+ /** @description The email address the user wants to switch to. */
4536
+ new_email: string;
4537
+ /** @description Override the account-wide policy. Can only raise the bar: passing `old_and_new` forces double verification; `new_only` is ignored if the account requires `old_and_new`. */
4538
+ verification_mode?: "new_only" | "old_and_new";
4539
+ /** @description Where to send the user after they click the link in the verification email. The status of the operation is appended as a `?status=applied|pending_old` query param so the calling app can render the right screen. When omitted, the user lands on the auth host's `/flow/email-change-done` fallback. */
4540
+ redirect_uri?: string;
4541
+ };
4542
+ };
4543
+ };
4544
+ responses: {
4545
+ /** @description Default Response */
4546
+ 200: {
4547
+ headers: {
4548
+ [name: string]: unknown;
4549
+ };
4550
+ content: {
4551
+ "application/json": {
4552
+ /** @enum {string} */
4553
+ status: "verification_sent";
4554
+ ticket_id: string;
4555
+ verification_mode: "new_only" | "old_and_new";
4556
+ };
4557
+ };
4558
+ };
4559
+ };
4560
+ };
4561
+ user_change_email_verify: {
4562
+ parameters: {
4563
+ query: {
4564
+ ticket: string;
4565
+ };
4566
+ header?: never;
4567
+ path?: never;
4568
+ cookie?: never;
4569
+ };
4570
+ requestBody?: never;
4571
+ responses: {
4572
+ /** @description Default Response */
4573
+ 200: {
4574
+ headers: {
4575
+ [name: string]: unknown;
4576
+ };
4577
+ content?: never;
4578
+ };
4579
+ };
4580
+ };
4581
+ "user/verifyEmailStart": {
4582
+ parameters: {
4583
+ query?: never;
4584
+ header?: never;
4585
+ path: {
4586
+ user_id: string;
4587
+ };
4588
+ cookie?: never;
4589
+ };
4590
+ /** @description Optional payload for `POST /user/:user_id/verify-email/start`. Trigger a verification email send for the given user. */
4591
+ requestBody: {
4592
+ content: {
4593
+ "application/json": {
4594
+ /** @description Where to send the user after they click the link. The status of the operation is appended as `?status=verified|already_verified|invalid_link|expired` so the calling app can render the right screen. When omitted, the user lands on the auth host's `/flow/verify-email-done` fallback. */
4595
+ redirect_uri?: string;
4596
+ };
4597
+ };
4598
+ };
4599
+ responses: {
4600
+ /** @description Default Response */
4601
+ 200: {
4602
+ headers: {
4603
+ [name: string]: unknown;
4604
+ };
4605
+ content: {
4606
+ "application/json": {
4607
+ status: "verification_sent" | "already_verified";
4608
+ ticket_id?: string;
4609
+ };
4610
+ };
4611
+ };
4612
+ };
4613
+ };
4614
+ user_verify_email_confirm: {
3776
4615
  parameters: {
3777
- query?: never;
3778
- header?: never;
3779
- path: {
3780
- user_id: string;
4616
+ query: {
4617
+ ticket: string;
3781
4618
  };
4619
+ header?: never;
4620
+ path?: never;
3782
4621
  cookie?: never;
3783
4622
  };
3784
4623
  requestBody?: never;
@@ -3963,6 +4802,8 @@ export interface operations {
3963
4802
  pageSize?: number;
3964
4803
  /** @description Filter using a FaableQL query */
3965
4804
  query?: string;
4805
+ /** @description Full-text search across: `name`, `description`. */
4806
+ q?: string;
3966
4807
  };
3967
4808
  header?: never;
3968
4809
  path?: never;
@@ -4091,6 +4932,61 @@ export interface operations {
4091
4932
  };
4092
4933
  };
4093
4934
  };
4935
+ "role/update": {
4936
+ parameters: {
4937
+ query?: never;
4938
+ header?: never;
4939
+ path: {
4940
+ role_id: string;
4941
+ };
4942
+ cookie?: never;
4943
+ };
4944
+ /** @description Partial update for a Role. Only the supplied fields are modified. */
4945
+ requestBody: {
4946
+ content: {
4947
+ "application/json": {
4948
+ /** @description New human-readable identifier for the role. */
4949
+ name?: string;
4950
+ /** @description New free-form description of what users in this role do. */
4951
+ description?: string;
4952
+ };
4953
+ };
4954
+ };
4955
+ responses: {
4956
+ /** @description Role */
4957
+ 200: {
4958
+ headers: {
4959
+ [name: string]: unknown;
4960
+ };
4961
+ content: {
4962
+ "application/json": {
4963
+ /** @description Role ID */
4964
+ id: string;
4965
+ /**
4966
+ * @description Short, human-readable identifier for the role (e.g. `admin`, `editor`, `billing-manager`). Surfaced in the dashboard role pickers.
4967
+ * @example admin
4968
+ */
4969
+ name: string;
4970
+ /** @description Free-form explanation of what users in this role are expected to do or have access to. Shown alongside the role in the dashboard. */
4971
+ description: string;
4972
+ /** @description Object is related with this account */
4973
+ account: string;
4974
+ /**
4975
+ * @description RoleMetadata
4976
+ * @default {}
4977
+ */
4978
+ metadata: {
4979
+ [key: string]: unknown;
4980
+ };
4981
+ /** @description Role creation date */
4982
+ createdAt: string;
4983
+ /** @description Role updated date */
4984
+ updatedAt?: string;
4985
+ };
4986
+ };
4987
+ };
4988
+ };
4989
+ };
4094
4990
  "role/remove": {
4095
4991
  parameters: {
4096
4992
  query?: never;
@@ -4343,6 +5239,8 @@ export interface operations {
4343
5239
  pageSize?: number;
4344
5240
  /** @description Filter using a FaableQL query */
4345
5241
  query?: string;
5242
+ /** @description Full-text search across: `name`, `slug`. */
5243
+ q?: string;
4346
5244
  };
4347
5245
  header?: never;
4348
5246
  path?: never;
@@ -4485,6 +5383,72 @@ export interface operations {
4485
5383
  };
4486
5384
  };
4487
5385
  };
5386
+ "team/update": {
5387
+ parameters: {
5388
+ query?: never;
5389
+ header?: never;
5390
+ path: {
5391
+ team_id: string;
5392
+ };
5393
+ cookie?: never;
5394
+ };
5395
+ /** @description Partial update for a Team. Only the supplied fields are modified. `slug` is auto-derived from `name` and is not user-editable. */
5396
+ requestBody: {
5397
+ content: {
5398
+ "application/json": {
5399
+ /** @description New human-readable name for the team. */
5400
+ name?: string;
5401
+ /** @description New free-form description for the team. */
5402
+ description?: string;
5403
+ /** @description Arbitrary key/value pairs attached to the team. Replaces the previous metadata entirely. */
5404
+ metadata?: {
5405
+ [key: string]: unknown;
5406
+ };
5407
+ };
5408
+ };
5409
+ };
5410
+ responses: {
5411
+ /** @description Team */
5412
+ 200: {
5413
+ headers: {
5414
+ [name: string]: unknown;
5415
+ };
5416
+ content: {
5417
+ "application/json": {
5418
+ /** @description Team ID */
5419
+ id: string;
5420
+ /**
5421
+ * @description Human-readable name of the team. Shown in the dashboard and in team-picker UI.
5422
+ * @example Acme Engineering
5423
+ */
5424
+ name: string;
5425
+ /**
5426
+ * @description URL-safe identifier auto-derived from `name`. Unique within the tenant; used in routes that address a team by slug.
5427
+ * @example acme-engineering
5428
+ */
5429
+ slug: string;
5430
+ /** @description Optional free-form description of the team. */
5431
+ description: string | null;
5432
+ /** @description Optional URL of an image used as the team avatar/logo. */
5433
+ logo_url: string | null;
5434
+ /** @description Object is related with this account */
5435
+ account: string;
5436
+ /**
5437
+ * @description TeamMetadata
5438
+ * @default {}
5439
+ */
5440
+ metadata: {
5441
+ [key: string]: unknown;
5442
+ };
5443
+ /** @description Team creation date */
5444
+ createdAt: string;
5445
+ /** @description Team updated date */
5446
+ updatedAt?: string;
5447
+ };
5448
+ };
5449
+ };
5450
+ };
5451
+ };
4488
5452
  "team/remove": {
4489
5453
  parameters: {
4490
5454
  query?: never;
@@ -4559,6 +5523,14 @@ export interface operations {
4559
5523
  * ]
4560
5524
  */
4561
5525
  users: string[];
5526
+ /**
5527
+ * @description Role ids to grant to the added members within the scope of this team.
5528
+ * @default []
5529
+ * @example [
5530
+ * "role_6555fd293acc2f0fac0e3452"
5531
+ * ]
5532
+ */
5533
+ roles?: string[];
4562
5534
  };
4563
5535
  };
4564
5536
  };
@@ -4672,6 +5644,8 @@ export interface operations {
4672
5644
  next?: string;
4673
5645
  /** @description Size of the results array */
4674
5646
  pageSize?: number;
5647
+ /** @description Expand id-only fields in the response. Accepts repeated params (`expand=user&expand=roles`) or comma-separated (`expand=user,roles`). */
5648
+ expand?: ("user" | "team" | "roles")[];
4675
5649
  };
4676
5650
  header?: never;
4677
5651
  path: {
@@ -4717,6 +5691,14 @@ export interface operations {
4717
5691
  * ]
4718
5692
  */
4719
5693
  users: string[];
5694
+ /**
5695
+ * @description Role ids to grant to the added members within the scope of this team.
5696
+ * @default []
5697
+ * @example [
5698
+ * "role_6555fd293acc2f0fac0e3452"
5699
+ * ]
5700
+ */
5701
+ roles?: string[];
4720
5702
  };
4721
5703
  };
4722
5704
  };
@@ -4806,6 +5788,182 @@ export interface operations {
4806
5788
  };
4807
5789
  };
4808
5790
  };
5791
+ "team/listInvites": {
5792
+ parameters: {
5793
+ query?: {
5794
+ /** @description FaableQL filter. Supported fields: `email`. Example: `?query=email:foo@bar.com` */
5795
+ query?: string;
5796
+ };
5797
+ header?: never;
5798
+ path: {
5799
+ team_id: string;
5800
+ };
5801
+ cookie?: never;
5802
+ };
5803
+ requestBody?: never;
5804
+ responses: {
5805
+ /** @description Default Response */
5806
+ 200: {
5807
+ headers: {
5808
+ [name: string]: unknown;
5809
+ };
5810
+ content: {
5811
+ "application/json": {
5812
+ data: {
5813
+ /** @description TeamInvite ID */
5814
+ id: string;
5815
+ /** @description Email address that was invited */
5816
+ email: string;
5817
+ /** @description Team the invitee will be added to upon acceptance. */
5818
+ team: components["schemas"]["Team"] | string | unknown;
5819
+ /** @description User that created the invitation, if known. */
5820
+ inviter?: components["schemas"]["User"] | string | unknown;
5821
+ /** @description Role ids that will be applied to the new TeamMember on acceptance. */
5822
+ roles: string[];
5823
+ /** @description `auto` adds the user directly if they already exist in the tenant and only falls back to a ticketed invite when the email is unknown. `invite` always issues a ticket + email regardless of whether the user exists. */
5824
+ mode: "auto" | "invite";
5825
+ /** @description URI to redirect the invitee to after a successful accept. */
5826
+ redirect_uri?: string;
5827
+ /** @description ISO 8601 timestamp at which the invite stops being valid. */
5828
+ expires_at: string;
5829
+ /** @description ISO 8601 timestamp at which the invite was accepted. Absent for pending invites. */
5830
+ consume_date?: string;
5831
+ /** @description Object is related with this account */
5832
+ account: string;
5833
+ /**
5834
+ * @description TeamInviteMetadata
5835
+ * @default {}
5836
+ */
5837
+ metadata: {
5838
+ [key: string]: unknown;
5839
+ };
5840
+ /** @description TeamInvite creation date */
5841
+ createdAt: string;
5842
+ /** @description TeamInvite updated date */
5843
+ updatedAt?: string;
5844
+ }[];
5845
+ };
5846
+ };
5847
+ };
5848
+ };
5849
+ };
5850
+ "team/invite": {
5851
+ parameters: {
5852
+ query?: never;
5853
+ header?: never;
5854
+ path: {
5855
+ team_id: string;
5856
+ };
5857
+ cookie?: never;
5858
+ };
5859
+ /** @description Payload for inviting a user to a team by email. `mode='auto'` (default) adds the user immediately if they already exist in the tenant and falls back to a ticketed invite otherwise. `mode='invite'` always issues a ticket + email. */
5860
+ requestBody: {
5861
+ content: {
5862
+ "application/json": {
5863
+ /**
5864
+ * @description Email of the user to invite to the team.
5865
+ * @example someone@example.com
5866
+ */
5867
+ email: string;
5868
+ /**
5869
+ * @description Role ids granted to the resulting TeamMember within the scope of this team.
5870
+ * @default []
5871
+ */
5872
+ roles?: string[];
5873
+ /** @description `auto` adds the user directly if they already exist in the tenant and only falls back to a ticketed invite when the email is unknown. `invite` always issues a ticket + email regardless of whether the user exists. */
5874
+ mode?: "auto" | "invite";
5875
+ /** @description Where to redirect the invitee after a successful accept. Defaults to `/`. */
5876
+ redirect_uri?: string;
5877
+ };
5878
+ };
5879
+ };
5880
+ responses: {
5881
+ /** @description Default Response */
5882
+ 200: {
5883
+ headers: {
5884
+ [name: string]: unknown;
5885
+ };
5886
+ content: {
5887
+ "application/json": {
5888
+ /** @description `invited` when a ticket + email was issued, `added` when the user was added directly (auto mode + existing user). */
5889
+ status: "invited" | "added";
5890
+ /** @description ID of the issued invite ticket (when status=invited). */
5891
+ ticket_id?: string;
5892
+ /** @description TeamMember */
5893
+ member?: {
5894
+ /** @description TeamMember ID */
5895
+ id: string;
5896
+ /** @description User that belongs to the team. Returned as an id by default; pass `?expand=user` to inline the full User object. */
5897
+ user: components["schemas"]["User"] | string | unknown;
5898
+ /** @description Team the user belongs to. Returned as an id by default; pass `?expand=team` to inline the full Team object. */
5899
+ team: components["schemas"]["Team"] | string | unknown;
5900
+ /** @description Roles granted to the user *within this team*. Distinct from account-wide RoleMember grants — these only apply in the scope of the team. Each entry is an id by default; pass `?expand=roles` to inline. */
5901
+ roles: (components["schemas"]["Role"] | string | unknown)[];
5902
+ /** @description Object is related with this account */
5903
+ account: string;
5904
+ /**
5905
+ * @description TeamMemberMetadata
5906
+ * @default {}
5907
+ */
5908
+ metadata: {
5909
+ [key: string]: unknown;
5910
+ };
5911
+ /** @description TeamMember creation date */
5912
+ createdAt: string;
5913
+ /** @description TeamMember updated date */
5914
+ updatedAt?: string;
5915
+ };
5916
+ };
5917
+ };
5918
+ };
5919
+ };
5920
+ };
5921
+ "team/revokeInvite": {
5922
+ parameters: {
5923
+ query?: never;
5924
+ header?: never;
5925
+ path: {
5926
+ team_id: string;
5927
+ ticket_id: string;
5928
+ };
5929
+ cookie?: never;
5930
+ };
5931
+ requestBody?: never;
5932
+ responses: {
5933
+ /** @description Default Response */
5934
+ 200: {
5935
+ headers: {
5936
+ [name: string]: unknown;
5937
+ };
5938
+ content: {
5939
+ "application/json": {
5940
+ /** @enum {string} */
5941
+ status: "revoked";
5942
+ };
5943
+ };
5944
+ };
5945
+ };
5946
+ };
5947
+ team_invite_verify: {
5948
+ parameters: {
5949
+ query: {
5950
+ ticket: string;
5951
+ };
5952
+ header?: never;
5953
+ path?: never;
5954
+ cookie?: never;
5955
+ };
5956
+ requestBody?: never;
5957
+ responses: {
5958
+ /** @description Default Response */
5959
+ 200: {
5960
+ headers: {
5961
+ [name: string]: unknown;
5962
+ };
5963
+ content?: never;
5964
+ };
5965
+ };
5966
+ };
4809
5967
  "api/list": {
4810
5968
  parameters: {
4811
5969
  query?: {
@@ -4817,6 +5975,8 @@ export interface operations {
4817
5975
  pageSize?: number;
4818
5976
  /** @description Filter using a FaableQL query */
4819
5977
  query?: string;
5978
+ /** @description Full-text search across: `name`, `description`, `identifier`, `slug`. */
5979
+ q?: string;
4820
5980
  };
4821
5981
  header?: never;
4822
5982
  path?: never;
@@ -5731,6 +6891,10 @@ export interface operations {
5731
6891
  pageSize?: number;
5732
6892
  /** @description Filter using a FaableQL query */
5733
6893
  query?: string;
6894
+ /** @description Expand id-only fields in the response. Pass one path per entry (e.g. `?expand=user`). */
6895
+ expand?: ("user" | "client" | "connection" | "team" | "identity")[];
6896
+ /** @description Full-text search across: `message`. */
6897
+ q?: string;
5734
6898
  };
5735
6899
  header?: never;
5736
6900
  path?: never;
@@ -5756,7 +6920,10 @@ export interface operations {
5756
6920
  };
5757
6921
  "log/get": {
5758
6922
  parameters: {
5759
- query?: never;
6923
+ query?: {
6924
+ /** @description Expand id-only fields in the response. Pass one path per entry (e.g. `?expand=user`). */
6925
+ expand?: ("user" | "client" | "connection" | "team" | "identity")[];
6926
+ };
5760
6927
  header?: never;
5761
6928
  path: {
5762
6929
  log_id: string;
@@ -5782,6 +6949,17 @@ export interface operations {
5782
6949
  message?: string;
5783
6950
  /** @description Type-specific structured payload */
5784
6951
  data?: unknown;
6952
+ user?: components["schemas"]["User"] | string | unknown;
6953
+ client?: components["schemas"]["Client"] | string | unknown;
6954
+ connection?: components["schemas"]["Connection"] | string | unknown;
6955
+ team?: components["schemas"]["Team"] | string | unknown;
6956
+ identity?: components["schemas"]["Identity"] | string | unknown;
6957
+ ticket?: string;
6958
+ /**
6959
+ * Format: date-time
6960
+ * @description When this log row will be auto-deleted by the Mongo TTL monitor. Absent on rows recorded without `ttl_seconds`.
6961
+ */
6962
+ expires_at?: string;
5785
6963
  /** @description Object is related with this account */
5786
6964
  account: string;
5787
6965
  /**
@@ -5831,6 +7009,8 @@ export interface operations {
5831
7009
  pageSize?: number;
5832
7010
  /** @description Filter using a FaableQL query */
5833
7011
  query?: string;
7012
+ /** @description Full-text search across: `domain`. */
7013
+ q?: string;
5834
7014
  };
5835
7015
  header?: never;
5836
7016
  path?: never;
@@ -6073,10 +7253,20 @@ export interface operations {
6073
7253
  * @default false
6074
7254
  */
6075
7255
  email_verified: boolean;
7256
+ /** @description How `email_verified` was last set. `manual` — admin flipped the flag via `POST /user/:id`. `verification_flow` — user clicked the verification link. `passwordless_otp` — user completed passwordless OTP login. `team_invite` — user clicked a team invitation link. `email_change` — user confirmed a self-service email change. `federated` — verified by the external IdP on OAuth callback. `null` — the field was cleared (admin un-verified the email). */
7257
+ email_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | null;
7258
+ /** @description ISO 8601 timestamp of when `email_verified` was last flipped to true. */
7259
+ email_verified_at?: string | null;
7260
+ /** @description ISO 8601 timestamp of the user's last verified email change. When set, OAuth callbacks will not overwrite `email`/`email_verified` from the federated provider — the manually-chosen email wins. */
7261
+ email_change_locked_at?: string | null;
6076
7262
  /** @description contact phone number */
6077
7263
  phone?: string | null;
6078
7264
  /** @description phone is verified */
6079
7265
  phone_verified: boolean;
7266
+ /** @description How `phone_verified` was last set. Same enum as `email_verified_method`. */
7267
+ phone_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | null;
7268
+ /** @description ISO 8601 timestamp of when `phone_verified` was last flipped to true. */
7269
+ phone_verified_at?: string | null;
6080
7270
  /** @description country iso code */
6081
7271
  country_iso?: string | null;
6082
7272
  /** @description user birth_date */