@faable/auth-sdk 2.7.28 → 2.7.30

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.
@@ -760,6 +760,46 @@ export interface paths {
760
760
  patch?: never;
761
761
  trace?: never;
762
762
  };
763
+ "/user/import": {
764
+ parameters: {
765
+ query?: never;
766
+ header?: never;
767
+ path?: never;
768
+ cookie?: never;
769
+ };
770
+ get?: never;
771
+ put?: never;
772
+ /**
773
+ * Import users, with their password hashes
774
+ * @description Creates up to 500 users per request, for migrations from another provider. Each row can carry a `password_hash` exported from that provider (bcrypt, scrypt, Firebase scrypt, PBKDF2, argon2): the user signs in with their existing password and the hash is upgraded to argon2id on that first login. Fast digests (MD5, SHA-1, SHA-2) and low costs are refused per row with `weak_password_hash`. Rows are matched by email, so the same file can be sent twice: existing users are `skipped` unless `update_existing`. A bad row never fails the batch: each row gets its own `status` and `error`. Imported users get none of the built-in new-user emails. The response never contains a hash, and neither does the audit log.
775
+ */
776
+ post: operations["user/import"];
777
+ delete?: never;
778
+ options?: never;
779
+ head?: never;
780
+ patch?: never;
781
+ trace?: never;
782
+ };
783
+ "/user/export": {
784
+ parameters: {
785
+ query?: never;
786
+ header?: never;
787
+ path?: never;
788
+ cookie?: never;
789
+ };
790
+ /**
791
+ * Export users, optionally with their password hashes
792
+ * @description Pages through every user of the tenant, 500 at a time, in the row shape `POST /user/import` takes. With `include_hashes` each row carries its `password_hash` (needs the `read:password_hashes` scope, is audited as `credentials.exported` and notifies its subscribers). Provider access and refresh tokens of linked identities are never exported. Available on every plan.
793
+ */
794
+ get: operations["user/export"];
795
+ put?: never;
796
+ post?: never;
797
+ delete?: never;
798
+ options?: never;
799
+ head?: never;
800
+ patch?: never;
801
+ trace?: never;
802
+ };
763
803
  "/identity": {
764
804
  parameters: {
765
805
  query?: never;
@@ -891,7 +931,7 @@ export interface paths {
891
931
  put?: never;
892
932
  /**
893
933
  * Set a credential's password
894
- * @description Sets or rotates the password for a database credential. The previous password is invalidated immediately. Records a `credential.password_changed` audit entry (initiated_by=admin) for traceability. The confirmation email is only sent when an EXISTING password is rotated: setting the first password on a credential that had none is a creation, not a change. The password is never returned.
934
+ * @description Sets or rotates the password for a database credential. Send exactly one of `password` (plaintext, hashed with argon2id) or `password_hash` (a hash exported from another provider: bcrypt, scrypt, Firebase scrypt, PBKDF2 or argon2 — verified on the first login and upgraded to argon2id). The previous password is invalidated immediately. A plaintext password records a `credential.password_changed` audit entry (initiated_by=admin); the confirmation email is only sent when an EXISTING password is rotated. An imported hash records `credential.password_imported` with its algorithm and sends no email. Neither the password nor the hash is ever returned or logged.
895
935
  */
896
936
  post: operations["credentials/setPassword"];
897
937
  delete?: never;
@@ -4727,8 +4767,8 @@ export interface components {
4727
4767
  * @default false
4728
4768
  */
4729
4769
  email_verified: boolean;
4730
- /** @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. `password_reset` — user completed the recovery link that was emailed to them (the `email` channel only). `null` — the field was cleared (admin un-verified the email). */
4731
- email_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | "sms_otp" | "password_reset" | null;
4770
+ /** @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. `password_reset` — user completed the recovery link that was emailed to them (the `email` channel only). `import` — the user arrived verified from another provider through `POST /user/import` (asserted by whoever ran the migration). `null` — the field was cleared (admin un-verified the email). */
4771
+ email_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | "sms_otp" | "password_reset" | "import" | null;
4732
4772
  /** @description ISO 8601 timestamp of when `email_verified` was last flipped to true. */
4733
4773
  email_verified_at?: string | null;
4734
4774
  /** @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. */
@@ -4737,6 +4777,8 @@ export interface components {
4737
4777
  email_bounced_at?: string | null;
4738
4778
  /** @description ISO 8601 timestamp of the built-in welcome email send. Set once by the platform; guarantees at most one welcome per user. */
4739
4779
  welcome_sent_at?: string | null;
4780
+ /** @description ISO 8601 timestamp of when the user was created by `POST /user/import`. Imported users get none of the built-in new-user emails (verification, welcome, `user.created` notifications); `user.created` webhooks still fire and carry this field. */
4781
+ imported_at?: string | null;
4740
4782
  /** @description ISO 8601 timestamp of the last time the hosted "create a passkey" offer was shown to this user after a login. Drives the snooze in `login_methods.passkey_promotion_snooze_days`. */
4741
4783
  passkey_prompted_at?: string | null;
4742
4784
  /** @description How many times the passkey offer has been shown to this user. Capped by `login_methods.passkey_promotion_max_prompts`; reset by an administrator through `POST /user/:id/passkey-prompt/reset`. */
@@ -4750,7 +4792,7 @@ export interface components {
4750
4792
  /** @description phone is verified */
4751
4793
  phone_verified: boolean;
4752
4794
  /** @description How `phone_verified` was last set. Same enum as `email_verified_method`, plus `sms_otp` — the user typed a code sent by SMS (`POST /user/:id/verify-phone/start`). */
4753
- phone_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | "sms_otp" | "password_reset" | null;
4795
+ phone_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | "sms_otp" | "password_reset" | "import" | null;
4754
4796
  /** @description ISO 8601 timestamp of when `phone_verified` was last flipped to true. */
4755
4797
  phone_verified_at?: string | null;
4756
4798
  /** @description country iso code */
@@ -6305,6 +6347,8 @@ export interface components {
6305
6347
  * - `same_email` (400): The new email is the same as the current one.
6306
6348
  * - `user_has_no_email` (400): The operation needs an email but the user has none.
6307
6349
  * - `password_too_weak` (400): The password does not meet the connection policy. `message` lists each unmet rule.
6350
+ * - `invalid_password_hash` (400): The imported password hash cannot be read, or its cost is above what a login can afford. `message` names the field.
6351
+ * - `weak_password_hash` (400): The imported password hash uses a fast digest (MD5, SHA-1, SHA-2) or a cost below the minimum. `message` says which.
6308
6352
  * - `invalid_code` (400): The verification code is wrong, expired or already used.
6309
6353
  * - `invalid_phone` (400): The phone number is not E.164 and could not be resolved with the account default country. Include the country code.
6310
6354
  * - `phone_changed` (400): The phone on the user changed after the code was sent. Start again.
@@ -6374,7 +6418,7 @@ export interface components {
6374
6418
  * - `revision_not_found` (404): The revision is not in the flow history.
6375
6419
  * @enum {string}
6376
6420
  */
6377
- ErrorCode: "bad_request" | "validation_error" | "unauthorized" | "payment_required" | "forbidden" | "not_found" | "method_not_allowed" | "conflict" | "payload_too_large" | "unsupported_media_type" | "unprocessable_entity" | "too_many_requests" | "internal_error" | "already_exists" | "invalid_id" | "account_not_found" | "invalid_query" | "search_not_supported" | "invalid_expand" | "access_denied" | "insufficient_scope" | "team_required" | "account_limit_reached" | "invalid_project_id" | "account_transfer_refused" | "plan_required" | "not_logged_in" | "invalid_token" | "not_owner" | "user_suspended" | "invalid_credentials" | "login_denied" | "signup_denied" | "client_credentials_denied" | "signup_disabled" | "email_taken" | "invalid_email" | "same_email" | "user_has_no_email" | "password_too_weak" | "invalid_code" | "invalid_phone" | "phone_changed" | "phone_already_verified" | "sms_unavailable" | "sms_failed" | "invalid_state" | "state_mismatch" | "invalid_ticket" | "ticket_used" | "ticket_expired" | "ticket_not_found" | "credential_not_found" | "invalid_link" | "expired_link" | "invalid_otp" | "invalid_client" | "client_not_found" | "client_mismatch" | "invalid_client_metadata" | "invalid_connection" | "connection_required" | "connection_misconfigured" | "passwordless_unavailable" | "ambiguous_connection" | "invalid_redirect_uri" | "origin_not_allowed" | "audience_not_found" | "system_resource" | "invalid_request" | "invalid_device_code" | "provider_error" | "identity_already_linked" | "identity_link_denied" | "identity_conflict" | "identity_orphaned" | "no_provider_token" | "no_refresh_token" | "action_unavailable" | "login_flow_misconfigured" | "mfa_required" | "step_up_required" | "interaction_required" | "passkey_login_disabled" | "mfa_pending" | "mfa_invalid_code" | "mfa_invalid_recovery_code" | "too_many_attempts" | "totp_not_allowed" | "no_usable_factor" | "factor_not_found" | "factor_already_confirmed" | "invalid_factor" | "session_missing" | "passkey_verification_failed" | "no_passkey_enrolled" | "malformed_credential" | "unknown_passkey" | "invalid_passkey" | "invite_not_found" | "invite_used" | "already_member" | "not_a_member" | "role_not_found" | "invalid_role" | "flow_not_found" | "revision_not_found";
6421
+ ErrorCode: "bad_request" | "validation_error" | "unauthorized" | "payment_required" | "forbidden" | "not_found" | "method_not_allowed" | "conflict" | "payload_too_large" | "unsupported_media_type" | "unprocessable_entity" | "too_many_requests" | "internal_error" | "already_exists" | "invalid_id" | "account_not_found" | "invalid_query" | "search_not_supported" | "invalid_expand" | "access_denied" | "insufficient_scope" | "team_required" | "account_limit_reached" | "invalid_project_id" | "account_transfer_refused" | "plan_required" | "not_logged_in" | "invalid_token" | "not_owner" | "user_suspended" | "invalid_credentials" | "login_denied" | "signup_denied" | "client_credentials_denied" | "signup_disabled" | "email_taken" | "invalid_email" | "same_email" | "user_has_no_email" | "password_too_weak" | "invalid_password_hash" | "weak_password_hash" | "invalid_code" | "invalid_phone" | "phone_changed" | "phone_already_verified" | "sms_unavailable" | "sms_failed" | "invalid_state" | "state_mismatch" | "invalid_ticket" | "ticket_used" | "ticket_expired" | "ticket_not_found" | "credential_not_found" | "invalid_link" | "expired_link" | "invalid_otp" | "invalid_client" | "client_not_found" | "client_mismatch" | "invalid_client_metadata" | "invalid_connection" | "connection_required" | "connection_misconfigured" | "passwordless_unavailable" | "ambiguous_connection" | "invalid_redirect_uri" | "origin_not_allowed" | "audience_not_found" | "system_resource" | "invalid_request" | "invalid_device_code" | "provider_error" | "identity_already_linked" | "identity_link_denied" | "identity_conflict" | "identity_orphaned" | "no_provider_token" | "no_refresh_token" | "action_unavailable" | "login_flow_misconfigured" | "mfa_required" | "step_up_required" | "interaction_required" | "passkey_login_disabled" | "mfa_pending" | "mfa_invalid_code" | "mfa_invalid_recovery_code" | "too_many_attempts" | "totp_not_allowed" | "no_usable_factor" | "factor_not_found" | "factor_already_confirmed" | "invalid_factor" | "session_missing" | "passkey_verification_failed" | "no_passkey_enrolled" | "malformed_credential" | "unknown_passkey" | "invalid_passkey" | "invite_not_found" | "invite_used" | "already_member" | "not_a_member" | "role_not_found" | "invalid_role" | "flow_not_found" | "revision_not_found";
6378
6422
  /** @description Every error response has this shape. Branch on `error_code`, never on `message`: the message is written for a person and may change. */
6379
6423
  ErrorResponse: {
6380
6424
  /** @description The HTTP status, repeated. */
@@ -10769,8 +10813,8 @@ export interface operations {
10769
10813
  * @default false
10770
10814
  */
10771
10815
  email_verified: boolean;
10772
- /** @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. `password_reset` — user completed the recovery link that was emailed to them (the `email` channel only). `null` — the field was cleared (admin un-verified the email). */
10773
- email_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | "sms_otp" | "password_reset" | null;
10816
+ /** @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. `password_reset` — user completed the recovery link that was emailed to them (the `email` channel only). `import` — the user arrived verified from another provider through `POST /user/import` (asserted by whoever ran the migration). `null` — the field was cleared (admin un-verified the email). */
10817
+ email_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | "sms_otp" | "password_reset" | "import" | null;
10774
10818
  /** @description ISO 8601 timestamp of when `email_verified` was last flipped to true. */
10775
10819
  email_verified_at?: string | null;
10776
10820
  /** @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. */
@@ -10779,6 +10823,8 @@ export interface operations {
10779
10823
  email_bounced_at?: string | null;
10780
10824
  /** @description ISO 8601 timestamp of the built-in welcome email send. Set once by the platform; guarantees at most one welcome per user. */
10781
10825
  welcome_sent_at?: string | null;
10826
+ /** @description ISO 8601 timestamp of when the user was created by `POST /user/import`. Imported users get none of the built-in new-user emails (verification, welcome, `user.created` notifications); `user.created` webhooks still fire and carry this field. */
10827
+ imported_at?: string | null;
10782
10828
  /** @description ISO 8601 timestamp of the last time the hosted "create a passkey" offer was shown to this user after a login. Drives the snooze in `login_methods.passkey_promotion_snooze_days`. */
10783
10829
  passkey_prompted_at?: string | null;
10784
10830
  /** @description How many times the passkey offer has been shown to this user. Capped by `login_methods.passkey_promotion_max_prompts`; reset by an administrator through `POST /user/:id/passkey-prompt/reset`. */
@@ -10792,7 +10838,7 @@ export interface operations {
10792
10838
  /** @description phone is verified */
10793
10839
  phone_verified: boolean;
10794
10840
  /** @description How `phone_verified` was last set. Same enum as `email_verified_method`, plus `sms_otp` — the user typed a code sent by SMS (`POST /user/:id/verify-phone/start`). */
10795
- phone_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | "sms_otp" | "password_reset" | null;
10841
+ phone_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | "sms_otp" | "password_reset" | "import" | null;
10796
10842
  /** @description ISO 8601 timestamp of when `phone_verified` was last flipped to true. */
10797
10843
  phone_verified_at?: string | null;
10798
10844
  /** @description country iso code */
@@ -10995,8 +11041,8 @@ export interface operations {
10995
11041
  * @default false
10996
11042
  */
10997
11043
  email_verified: boolean;
10998
- /** @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. `password_reset` — user completed the recovery link that was emailed to them (the `email` channel only). `null` — the field was cleared (admin un-verified the email). */
10999
- email_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | "sms_otp" | "password_reset" | null;
11044
+ /** @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. `password_reset` — user completed the recovery link that was emailed to them (the `email` channel only). `import` — the user arrived verified from another provider through `POST /user/import` (asserted by whoever ran the migration). `null` — the field was cleared (admin un-verified the email). */
11045
+ email_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | "sms_otp" | "password_reset" | "import" | null;
11000
11046
  /** @description ISO 8601 timestamp of when `email_verified` was last flipped to true. */
11001
11047
  email_verified_at?: string | null;
11002
11048
  /** @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. */
@@ -11005,6 +11051,8 @@ export interface operations {
11005
11051
  email_bounced_at?: string | null;
11006
11052
  /** @description ISO 8601 timestamp of the built-in welcome email send. Set once by the platform; guarantees at most one welcome per user. */
11007
11053
  welcome_sent_at?: string | null;
11054
+ /** @description ISO 8601 timestamp of when the user was created by `POST /user/import`. Imported users get none of the built-in new-user emails (verification, welcome, `user.created` notifications); `user.created` webhooks still fire and carry this field. */
11055
+ imported_at?: string | null;
11008
11056
  /** @description ISO 8601 timestamp of the last time the hosted "create a passkey" offer was shown to this user after a login. Drives the snooze in `login_methods.passkey_promotion_snooze_days`. */
11009
11057
  passkey_prompted_at?: string | null;
11010
11058
  /** @description How many times the passkey offer has been shown to this user. Capped by `login_methods.passkey_promotion_max_prompts`; reset by an administrator through `POST /user/:id/passkey-prompt/reset`. */
@@ -11018,7 +11066,7 @@ export interface operations {
11018
11066
  /** @description phone is verified */
11019
11067
  phone_verified: boolean;
11020
11068
  /** @description How `phone_verified` was last set. Same enum as `email_verified_method`, plus `sms_otp` — the user typed a code sent by SMS (`POST /user/:id/verify-phone/start`). */
11021
- phone_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | "sms_otp" | "password_reset" | null;
11069
+ phone_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | "sms_otp" | "password_reset" | "import" | null;
11022
11070
  /** @description ISO 8601 timestamp of when `phone_verified` was last flipped to true. */
11023
11071
  phone_verified_at?: string | null;
11024
11072
  /** @description country iso code */
@@ -11265,8 +11313,8 @@ export interface operations {
11265
11313
  * @default false
11266
11314
  */
11267
11315
  email_verified: boolean;
11268
- /** @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. `password_reset` — user completed the recovery link that was emailed to them (the `email` channel only). `null` — the field was cleared (admin un-verified the email). */
11269
- email_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | "sms_otp" | "password_reset" | null;
11316
+ /** @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. `password_reset` — user completed the recovery link that was emailed to them (the `email` channel only). `import` — the user arrived verified from another provider through `POST /user/import` (asserted by whoever ran the migration). `null` — the field was cleared (admin un-verified the email). */
11317
+ email_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | "sms_otp" | "password_reset" | "import" | null;
11270
11318
  /** @description ISO 8601 timestamp of when `email_verified` was last flipped to true. */
11271
11319
  email_verified_at?: string | null;
11272
11320
  /** @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. */
@@ -11275,6 +11323,8 @@ export interface operations {
11275
11323
  email_bounced_at?: string | null;
11276
11324
  /** @description ISO 8601 timestamp of the built-in welcome email send. Set once by the platform; guarantees at most one welcome per user. */
11277
11325
  welcome_sent_at?: string | null;
11326
+ /** @description ISO 8601 timestamp of when the user was created by `POST /user/import`. Imported users get none of the built-in new-user emails (verification, welcome, `user.created` notifications); `user.created` webhooks still fire and carry this field. */
11327
+ imported_at?: string | null;
11278
11328
  /** @description ISO 8601 timestamp of the last time the hosted "create a passkey" offer was shown to this user after a login. Drives the snooze in `login_methods.passkey_promotion_snooze_days`. */
11279
11329
  passkey_prompted_at?: string | null;
11280
11330
  /** @description How many times the passkey offer has been shown to this user. Capped by `login_methods.passkey_promotion_max_prompts`; reset by an administrator through `POST /user/:id/passkey-prompt/reset`. */
@@ -11288,7 +11338,7 @@ export interface operations {
11288
11338
  /** @description phone is verified */
11289
11339
  phone_verified: boolean;
11290
11340
  /** @description How `phone_verified` was last set. Same enum as `email_verified_method`, plus `sms_otp` — the user typed a code sent by SMS (`POST /user/:id/verify-phone/start`). */
11291
- phone_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | "sms_otp" | "password_reset" | null;
11341
+ phone_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | "sms_otp" | "password_reset" | "import" | null;
11292
11342
  /** @description ISO 8601 timestamp of when `phone_verified` was last flipped to true. */
11293
11343
  phone_verified_at?: string | null;
11294
11344
  /** @description country iso code */
@@ -11497,8 +11547,8 @@ export interface operations {
11497
11547
  * @default false
11498
11548
  */
11499
11549
  email_verified: boolean;
11500
- /** @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. `password_reset` — user completed the recovery link that was emailed to them (the `email` channel only). `null` — the field was cleared (admin un-verified the email). */
11501
- email_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | "sms_otp" | "password_reset" | null;
11550
+ /** @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. `password_reset` — user completed the recovery link that was emailed to them (the `email` channel only). `import` — the user arrived verified from another provider through `POST /user/import` (asserted by whoever ran the migration). `null` — the field was cleared (admin un-verified the email). */
11551
+ email_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | "sms_otp" | "password_reset" | "import" | null;
11502
11552
  /** @description ISO 8601 timestamp of when `email_verified` was last flipped to true. */
11503
11553
  email_verified_at?: string | null;
11504
11554
  /** @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. */
@@ -11507,6 +11557,8 @@ export interface operations {
11507
11557
  email_bounced_at?: string | null;
11508
11558
  /** @description ISO 8601 timestamp of the built-in welcome email send. Set once by the platform; guarantees at most one welcome per user. */
11509
11559
  welcome_sent_at?: string | null;
11560
+ /** @description ISO 8601 timestamp of when the user was created by `POST /user/import`. Imported users get none of the built-in new-user emails (verification, welcome, `user.created` notifications); `user.created` webhooks still fire and carry this field. */
11561
+ imported_at?: string | null;
11510
11562
  /** @description ISO 8601 timestamp of the last time the hosted "create a passkey" offer was shown to this user after a login. Drives the snooze in `login_methods.passkey_promotion_snooze_days`. */
11511
11563
  passkey_prompted_at?: string | null;
11512
11564
  /** @description How many times the passkey offer has been shown to this user. Capped by `login_methods.passkey_promotion_max_prompts`; reset by an administrator through `POST /user/:id/passkey-prompt/reset`. */
@@ -11520,7 +11572,7 @@ export interface operations {
11520
11572
  /** @description phone is verified */
11521
11573
  phone_verified: boolean;
11522
11574
  /** @description How `phone_verified` was last set. Same enum as `email_verified_method`, plus `sms_otp` — the user typed a code sent by SMS (`POST /user/:id/verify-phone/start`). */
11523
- phone_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | "sms_otp" | "password_reset" | null;
11575
+ phone_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | "sms_otp" | "password_reset" | "import" | null;
11524
11576
  /** @description ISO 8601 timestamp of when `phone_verified` was last flipped to true. */
11525
11577
  phone_verified_at?: string | null;
11526
11578
  /** @description country iso code */
@@ -13114,6 +13166,326 @@ export interface operations {
13114
13166
  };
13115
13167
  };
13116
13168
  };
13169
+ "user/import": {
13170
+ parameters: {
13171
+ query?: never;
13172
+ header?: never;
13173
+ path?: never;
13174
+ cookie?: never;
13175
+ };
13176
+ requestBody: {
13177
+ content: {
13178
+ "application/json": {
13179
+ users: {
13180
+ /** @description The user's email. */
13181
+ email: string;
13182
+ /** @description The email was verified at the previous provider. Recorded with `email_verified_method: import`. */
13183
+ email_verified?: boolean;
13184
+ name?: string;
13185
+ given_name?: string;
13186
+ family_name?: string;
13187
+ phone?: string;
13188
+ birth_date?: string;
13189
+ locale?: string;
13190
+ picture?: string;
13191
+ /** @description User Metadata */
13192
+ user_metadata?: {
13193
+ [key: string]: unknown;
13194
+ };
13195
+ /** @description App Metadata */
13196
+ app_metadata?: {
13197
+ [key: string]: unknown;
13198
+ };
13199
+ /** @description A password hash exported from another provider. Verified on the first login and upgraded to argon2id. Fast digests (MD5, SHA-1, SHA-2) and low costs are refused with `weak_password_hash`. */
13200
+ password_hash?: string | {
13201
+ /** @description `bcrypt`, `argon2id`, `argon2i`, `argon2d`, `scrypt`, `pbkdf2-sha256`, `pbkdf2-sha512` or `firebase-scrypt`. */
13202
+ algorithm: string;
13203
+ /** @description The hash, or its base64 digest when `salt` is given. */
13204
+ hash: string;
13205
+ /** @description Base64 salt. */
13206
+ salt?: string;
13207
+ /** @description Algorithm parameters: `iterations` (pbkdf2); `N`, `r`, `p` (scrypt); `signer_key`, `salt_separator`, `rounds`, `mem_cost` (firebase-scrypt). */
13208
+ params?: {
13209
+ [key: string]: number | string;
13210
+ };
13211
+ };
13212
+ identities?: {
13213
+ /** @description connection_name of the social/enterprise connection. */
13214
+ connection: string;
13215
+ /** @description The user's id at the provider (GitHub id, Google `sub`…), so their first social login finds this user instead of creating a new one. */
13216
+ identity_id: string;
13217
+ /** @description Provider profile, stored as-is. */
13218
+ profile_data?: {
13219
+ [key: string]: unknown;
13220
+ };
13221
+ }[];
13222
+ }[];
13223
+ /** @description connection_name of the database connection the password hashes go to. Defaults to the tenant database connection. */
13224
+ connection?: string;
13225
+ /**
13226
+ * @description Set the password hash and identities of users that already exist (matched by email) instead of skipping them. Their profile is never overwritten.
13227
+ * @default false
13228
+ */
13229
+ update_existing?: boolean;
13230
+ /**
13231
+ * @description Validate every row and resolve every match without writing anything.
13232
+ * @default false
13233
+ */
13234
+ dry_run?: boolean;
13235
+ };
13236
+ };
13237
+ };
13238
+ responses: {
13239
+ /** @description Default Response */
13240
+ 200: {
13241
+ headers: {
13242
+ [name: string]: unknown;
13243
+ };
13244
+ content: {
13245
+ "application/json": {
13246
+ summary: {
13247
+ total: number;
13248
+ created: number;
13249
+ updated: number;
13250
+ skipped: number;
13251
+ error: number;
13252
+ };
13253
+ results: {
13254
+ /** @description Position of the row in `users`. */
13255
+ index: number;
13256
+ email: string;
13257
+ status: "created" | "updated" | "skipped" | "error";
13258
+ user_id?: string;
13259
+ error?: {
13260
+ code: string;
13261
+ message: string;
13262
+ };
13263
+ }[];
13264
+ };
13265
+ };
13266
+ };
13267
+ /** @description `validation_error` — The body, query or path failed schema validation. `details.issues` lists each failing field. */
13268
+ 400: {
13269
+ headers: {
13270
+ [name: string]: unknown;
13271
+ };
13272
+ content: {
13273
+ "application/json": components["schemas"]["ErrorResponse"] & {
13274
+ /** @enum {string} */
13275
+ error_code?: "validation_error";
13276
+ };
13277
+ };
13278
+ };
13279
+ /** @description `unauthorized` — The request carries no valid credentials. */
13280
+ 401: {
13281
+ headers: {
13282
+ [name: string]: unknown;
13283
+ };
13284
+ content: {
13285
+ "application/json": components["schemas"]["ErrorResponse"] & {
13286
+ /** @enum {string} */
13287
+ error_code?: "unauthorized";
13288
+ };
13289
+ };
13290
+ };
13291
+ /**
13292
+ * @description `forbidden` — The credentials are valid but do not allow this operation.
13293
+ *
13294
+ * `insufficient_scope` — The token lacks a scope this operation requires. `message` names it.
13295
+ *
13296
+ * `user_suspended` — The user is suspended and cannot sign in or be modified.
13297
+ */
13298
+ 403: {
13299
+ headers: {
13300
+ [name: string]: unknown;
13301
+ };
13302
+ content: {
13303
+ "application/json": components["schemas"]["ErrorResponse"] & {
13304
+ /** @enum {string} */
13305
+ error_code?: "forbidden" | "insufficient_scope" | "user_suspended";
13306
+ };
13307
+ };
13308
+ };
13309
+ /** @description `account_not_found` — No Auth Account matches the request (domain, header or token). */
13310
+ 404: {
13311
+ headers: {
13312
+ [name: string]: unknown;
13313
+ };
13314
+ content: {
13315
+ "application/json": components["schemas"]["ErrorResponse"] & {
13316
+ /** @enum {string} */
13317
+ error_code?: "account_not_found";
13318
+ };
13319
+ };
13320
+ };
13321
+ /** @description `too_many_requests` — Rate limit exceeded. Honour the `Retry-After` header. */
13322
+ 429: {
13323
+ headers: {
13324
+ [name: string]: unknown;
13325
+ };
13326
+ content: {
13327
+ "application/json": components["schemas"]["ErrorResponse"] & {
13328
+ /** @enum {string} */
13329
+ error_code?: "too_many_requests";
13330
+ };
13331
+ };
13332
+ };
13333
+ /** @description `internal_error` — Unexpected server error. Retry later; the request id is logged. */
13334
+ 500: {
13335
+ headers: {
13336
+ [name: string]: unknown;
13337
+ };
13338
+ content: {
13339
+ "application/json": components["schemas"]["ErrorResponse"] & {
13340
+ /** @enum {string} */
13341
+ error_code?: "internal_error";
13342
+ };
13343
+ };
13344
+ };
13345
+ };
13346
+ };
13347
+ "user/export": {
13348
+ parameters: {
13349
+ query?: {
13350
+ /** @description `next_cursor` of the previous page. */
13351
+ cursor?: string;
13352
+ limit?: number;
13353
+ /** @description connection_name of the database connection whose password hashes are exported. Defaults to the tenant database connection. */
13354
+ connection?: string;
13355
+ /** @description Include `password_hash`. Needs the `read:password_hashes` scope, is written to the audit log and notifies the `credentials.exported` subscribers. */
13356
+ include_hashes?: boolean;
13357
+ };
13358
+ header?: never;
13359
+ path?: never;
13360
+ cookie?: never;
13361
+ };
13362
+ requestBody?: never;
13363
+ responses: {
13364
+ /** @description Default Response */
13365
+ 200: {
13366
+ headers: {
13367
+ [name: string]: unknown;
13368
+ };
13369
+ content: {
13370
+ "application/json": {
13371
+ users: {
13372
+ user_id: string;
13373
+ email: string | null;
13374
+ email_verified: boolean;
13375
+ name?: string;
13376
+ given_name?: string;
13377
+ family_name?: string;
13378
+ phone?: string;
13379
+ birth_date?: string;
13380
+ locale?: string;
13381
+ picture?: string;
13382
+ user_metadata?: {
13383
+ [key: string]: unknown;
13384
+ };
13385
+ app_metadata?: {
13386
+ [key: string]: unknown;
13387
+ };
13388
+ /** @description `legacy_unexportable`: the password is still stored in a pre-2026 format that is not exported; it upgrades on the next login. */
13389
+ password_hash_status: "set" | "not_set" | "no_credential" | "legacy_unexportable";
13390
+ /** @description Self-describing hash (argon2id PHC for passwords set on Faable; the original format for imported ones not yet upgraded). Only with `include_hashes`. */
13391
+ password_hash?: string;
13392
+ identities?: {
13393
+ connection: string;
13394
+ identity_id: string;
13395
+ profile_data?: {
13396
+ [key: string]: unknown;
13397
+ };
13398
+ }[];
13399
+ }[];
13400
+ next_cursor: string | null;
13401
+ connection: string | null;
13402
+ };
13403
+ };
13404
+ };
13405
+ /**
13406
+ * @description `invalid_connection` — The connection does not exist, is disabled, or is not of the type this flow needs.
13407
+ *
13408
+ * `validation_error` — The body, query or path failed schema validation. `details.issues` lists each failing field.
13409
+ */
13410
+ 400: {
13411
+ headers: {
13412
+ [name: string]: unknown;
13413
+ };
13414
+ content: {
13415
+ "application/json": components["schemas"]["ErrorResponse"] & {
13416
+ /** @enum {string} */
13417
+ error_code?: "invalid_connection" | "validation_error";
13418
+ };
13419
+ };
13420
+ };
13421
+ /** @description `unauthorized` — The request carries no valid credentials. */
13422
+ 401: {
13423
+ headers: {
13424
+ [name: string]: unknown;
13425
+ };
13426
+ content: {
13427
+ "application/json": components["schemas"]["ErrorResponse"] & {
13428
+ /** @enum {string} */
13429
+ error_code?: "unauthorized";
13430
+ };
13431
+ };
13432
+ };
13433
+ /**
13434
+ * @description `forbidden` — The credentials are valid but do not allow this operation.
13435
+ *
13436
+ * `insufficient_scope` — The token lacks a scope this operation requires. `message` names it.
13437
+ *
13438
+ * `user_suspended` — The user is suspended and cannot sign in or be modified.
13439
+ */
13440
+ 403: {
13441
+ headers: {
13442
+ [name: string]: unknown;
13443
+ };
13444
+ content: {
13445
+ "application/json": components["schemas"]["ErrorResponse"] & {
13446
+ /** @enum {string} */
13447
+ error_code?: "forbidden" | "insufficient_scope" | "user_suspended";
13448
+ };
13449
+ };
13450
+ };
13451
+ /** @description `account_not_found` — No Auth Account matches the request (domain, header or token). */
13452
+ 404: {
13453
+ headers: {
13454
+ [name: string]: unknown;
13455
+ };
13456
+ content: {
13457
+ "application/json": components["schemas"]["ErrorResponse"] & {
13458
+ /** @enum {string} */
13459
+ error_code?: "account_not_found";
13460
+ };
13461
+ };
13462
+ };
13463
+ /** @description `too_many_requests` — Rate limit exceeded. Honour the `Retry-After` header. */
13464
+ 429: {
13465
+ headers: {
13466
+ [name: string]: unknown;
13467
+ };
13468
+ content: {
13469
+ "application/json": components["schemas"]["ErrorResponse"] & {
13470
+ /** @enum {string} */
13471
+ error_code?: "too_many_requests";
13472
+ };
13473
+ };
13474
+ };
13475
+ /** @description `internal_error` — Unexpected server error. Retry later; the request id is logged. */
13476
+ 500: {
13477
+ headers: {
13478
+ [name: string]: unknown;
13479
+ };
13480
+ content: {
13481
+ "application/json": components["schemas"]["ErrorResponse"] & {
13482
+ /** @enum {string} */
13483
+ error_code?: "internal_error";
13484
+ };
13485
+ };
13486
+ };
13487
+ };
13488
+ };
13117
13489
  "identity/list": {
13118
13490
  parameters: {
13119
13491
  query?: {
@@ -14453,7 +14825,20 @@ export interface operations {
14453
14825
  content: {
14454
14826
  "application/json": {
14455
14827
  /** @description New plaintext password (hashed on write). */
14456
- password: string;
14828
+ password?: string;
14829
+ /** @description A password hash exported from another provider. Verified on the first login and upgraded to argon2id. Fast digests (MD5, SHA-1, SHA-2) and low costs are refused with `weak_password_hash`. */
14830
+ password_hash?: string | {
14831
+ /** @description `bcrypt`, `argon2id`, `argon2i`, `argon2d`, `scrypt`, `pbkdf2-sha256`, `pbkdf2-sha512` or `firebase-scrypt`. */
14832
+ algorithm: string;
14833
+ /** @description The hash, or its base64 digest when `salt` is given. */
14834
+ hash: string;
14835
+ /** @description Base64 salt. */
14836
+ salt?: string;
14837
+ /** @description Algorithm parameters: `iterations` (pbkdf2); `N`, `r`, `p` (scrypt); `signer_key`, `salt_separator`, `rounds`, `mem_cost` (firebase-scrypt). */
14838
+ params?: {
14839
+ [key: string]: number | string;
14840
+ };
14841
+ };
14457
14842
  };
14458
14843
  };
14459
14844
  };
@@ -14489,7 +14874,15 @@ export interface operations {
14489
14874
  };
14490
14875
  };
14491
14876
  };
14492
- /** @description `validation_error` — The body, query or path failed schema validation. `details.issues` lists each failing field. */
14877
+ /**
14878
+ * @description `bad_request` — The request is malformed. `message` says what is wrong.
14879
+ *
14880
+ * `invalid_password_hash` — The imported password hash cannot be read, or its cost is above what a login can afford. `message` names the field.
14881
+ *
14882
+ * `weak_password_hash` — The imported password hash uses a fast digest (MD5, SHA-1, SHA-2) or a cost below the minimum. `message` says which.
14883
+ *
14884
+ * `validation_error` — The body, query or path failed schema validation. `details.issues` lists each failing field.
14885
+ */
14493
14886
  400: {
14494
14887
  headers: {
14495
14888
  [name: string]: unknown;
@@ -14497,7 +14890,7 @@ export interface operations {
14497
14890
  content: {
14498
14891
  "application/json": components["schemas"]["ErrorResponse"] & {
14499
14892
  /** @enum {string} */
14500
- error_code?: "validation_error";
14893
+ error_code?: "bad_request" | "invalid_password_hash" | "weak_password_hash" | "validation_error";
14501
14894
  };
14502
14895
  };
14503
14896
  };
@@ -24049,8 +24442,8 @@ export interface operations {
24049
24442
  * @default false
24050
24443
  */
24051
24444
  email_verified: boolean;
24052
- /** @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. `password_reset` — user completed the recovery link that was emailed to them (the `email` channel only). `null` — the field was cleared (admin un-verified the email). */
24053
- email_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | "sms_otp" | "password_reset" | null;
24445
+ /** @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. `password_reset` — user completed the recovery link that was emailed to them (the `email` channel only). `import` — the user arrived verified from another provider through `POST /user/import` (asserted by whoever ran the migration). `null` — the field was cleared (admin un-verified the email). */
24446
+ email_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | "sms_otp" | "password_reset" | "import" | null;
24054
24447
  /** @description ISO 8601 timestamp of when `email_verified` was last flipped to true. */
24055
24448
  email_verified_at?: string | null;
24056
24449
  /** @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. */
@@ -24059,6 +24452,8 @@ export interface operations {
24059
24452
  email_bounced_at?: string | null;
24060
24453
  /** @description ISO 8601 timestamp of the built-in welcome email send. Set once by the platform; guarantees at most one welcome per user. */
24061
24454
  welcome_sent_at?: string | null;
24455
+ /** @description ISO 8601 timestamp of when the user was created by `POST /user/import`. Imported users get none of the built-in new-user emails (verification, welcome, `user.created` notifications); `user.created` webhooks still fire and carry this field. */
24456
+ imported_at?: string | null;
24062
24457
  /** @description ISO 8601 timestamp of the last time the hosted "create a passkey" offer was shown to this user after a login. Drives the snooze in `login_methods.passkey_promotion_snooze_days`. */
24063
24458
  passkey_prompted_at?: string | null;
24064
24459
  /** @description How many times the passkey offer has been shown to this user. Capped by `login_methods.passkey_promotion_max_prompts`; reset by an administrator through `POST /user/:id/passkey-prompt/reset`. */
@@ -24072,7 +24467,7 @@ export interface operations {
24072
24467
  /** @description phone is verified */
24073
24468
  phone_verified: boolean;
24074
24469
  /** @description How `phone_verified` was last set. Same enum as `email_verified_method`, plus `sms_otp` — the user typed a code sent by SMS (`POST /user/:id/verify-phone/start`). */
24075
- phone_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | "sms_otp" | "password_reset" | null;
24470
+ phone_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | "sms_otp" | "password_reset" | "import" | null;
24076
24471
  /** @description ISO 8601 timestamp of when `phone_verified` was last flipped to true. */
24077
24472
  phone_verified_at?: string | null;
24078
24473
  /** @description country iso code */
@@ -24334,8 +24729,8 @@ export interface operations {
24334
24729
  * @default false
24335
24730
  */
24336
24731
  email_verified: boolean;
24337
- /** @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. `password_reset` — user completed the recovery link that was emailed to them (the `email` channel only). `null` — the field was cleared (admin un-verified the email). */
24338
- email_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | "sms_otp" | "password_reset" | null;
24732
+ /** @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. `password_reset` — user completed the recovery link that was emailed to them (the `email` channel only). `import` — the user arrived verified from another provider through `POST /user/import` (asserted by whoever ran the migration). `null` — the field was cleared (admin un-verified the email). */
24733
+ email_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | "sms_otp" | "password_reset" | "import" | null;
24339
24734
  /** @description ISO 8601 timestamp of when `email_verified` was last flipped to true. */
24340
24735
  email_verified_at?: string | null;
24341
24736
  /** @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. */
@@ -24344,6 +24739,8 @@ export interface operations {
24344
24739
  email_bounced_at?: string | null;
24345
24740
  /** @description ISO 8601 timestamp of the built-in welcome email send. Set once by the platform; guarantees at most one welcome per user. */
24346
24741
  welcome_sent_at?: string | null;
24742
+ /** @description ISO 8601 timestamp of when the user was created by `POST /user/import`. Imported users get none of the built-in new-user emails (verification, welcome, `user.created` notifications); `user.created` webhooks still fire and carry this field. */
24743
+ imported_at?: string | null;
24347
24744
  /** @description ISO 8601 timestamp of the last time the hosted "create a passkey" offer was shown to this user after a login. Drives the snooze in `login_methods.passkey_promotion_snooze_days`. */
24348
24745
  passkey_prompted_at?: string | null;
24349
24746
  /** @description How many times the passkey offer has been shown to this user. Capped by `login_methods.passkey_promotion_max_prompts`; reset by an administrator through `POST /user/:id/passkey-prompt/reset`. */
@@ -24357,7 +24754,7 @@ export interface operations {
24357
24754
  /** @description phone is verified */
24358
24755
  phone_verified: boolean;
24359
24756
  /** @description How `phone_verified` was last set. Same enum as `email_verified_method`, plus `sms_otp` — the user typed a code sent by SMS (`POST /user/:id/verify-phone/start`). */
24360
- phone_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | "sms_otp" | "password_reset" | null;
24757
+ phone_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | "sms_otp" | "password_reset" | "import" | null;
24361
24758
  /** @description ISO 8601 timestamp of when `phone_verified` was last flipped to true. */
24362
24759
  phone_verified_at?: string | null;
24363
24760
  /** @description country iso code */