Removing a phone credential
Profile & credentialsA signed-in user unlinks their phone. STEP-UP action (counterpart to adding a phone, scenario 29). Refused if it would leave the account with zero credentials.
- DELETE /v1/me/phone → unlink the phone (step-up: currentPassword or otpCode)
/v1/me/phoneauthUnlink phone (step-up)Step-up: a password-holding user supplies currentPassword; a password-less user an otpCode (from POST /v1/me/mfa/otp/request). TWO separate guards, both returning 409. (1) last_credential — refused if the phone is the user's ONLY credential (e.g. a phone-first account from scenario 3); an email counts only if it is VERIFIED, since login refuses an unverified one. (2) PRIMARY-CHANNEL — refused, and ENFORCED rather than merely advised, while login_mode = 'phone'. That case is a HARD lockout the last-credential guard cannot catch: it asks “is any credential left?” (yes — email + password), not “can the login this account will actually be asked to complete still be completed?”. With the number gone, every new-device challenge would still be planned on the phone channel and could neither be delivered nor satisfied. Switch the channel first (scenario 31), then remove. Unlinking also DROPS any phone_otp MFA method bound to the number — leaving it enrolled would advertise a second factor whose channel no longer existed, moving the same lockout one hop later; ensure another factor remains or re-enrol (scenario 25).
Field guide — what each value means & where it comes from2 fields
Unlinks the caller's verified phone. Requires Auth (the tester sends accessToken + x-gateway-context). Step-up re-auth: supply AT LEAST ONE factor — a password-holding user supplies currentPassword, a password-less (phone-only) user supplies otpCode. The body is .strict(). TWO guards then apply, both 409: last_credential (a phone-only user cannot remove their only credential — an email counts only if VERIFIED, since login refuses an unverified one), and the PRIMARY-CHANNEL guard, which refuses while login_mode = 'phone' because the account's new-device challenge would then target a number it no longer holds. Switch the channel first (scenario 31). Unlinking also drops any phone_otp MFA method bound to the number.
currentPasswordbodystringconditionalyou chooseotpCodebodystringconditionalout-of-bandDELETE https://api.kerja.team/v1/me/phoneResponse guide — what comes back & what each value meansno body
200 OK with the standard { data } envelope, where data is an empty object ({}). The phone is unlinked (phone and phoneVerifiedAt cleared, user.upserted enqueued, phone_unlinked audited) but the success body carries no fields. No notable response headers (no Set-Cookie, no Cache-Control: no-store).