---
title: "Remove phone"
method: DELETE
path: "/api/v1/me/phones/{id}"
tags: ["Phones"]
---

# Remove phone

`DELETE /api/v1/me/phones/{id}`

## Request

- Base URL: `https://api.proof.holdings`
- URL: `https://api.proof.holdings/api/v1/me/phones/{id}`
- Auth: API key in cookie `auth_token`

Remove a phone number from the account (h-implement-proper-deletion, PE-2). Refused with 409 while it is the identifier this session signed in with (`login_identifier`), the last sign-in method across phones and emails (`last_login_method`), or the last phone while an active Proof of Me circle exists (`circles_need_phone`). Otherwise, after a single-use `phone_remove` step-up grant bound to this id is consumed (`403 2fa_required` without one; `reason: target_mismatch` when the grant names other ids): every proof of a phone number is revoked, approval consents naming it are revoked, approval setups left without an approver are marked and their pending requests declined, the primary flag moves deterministically to the oldest remaining phone and active circles follow it, the row is hard-deleted, the other sessions are signed out, and a notice goes to the contacts captured before the delete. The response names the new primary. Cannot be undone. `GET /me/phones/{id}/removal-preview` shows the same counts beforehand.

## Path parameters

- `id` string, required: MongoDB ObjectId

## Response `200`

Phone removed — the cascade, line by line

- IdentifierRemovedResponse: The cascade a removal performed, line by line — the same lines the notice carries.
  - `success` true, required
  - `type` 'phone' | 'email', required
  - `removed_id` string, required
  - `identifier` string, required: Masked.
  - `proofs_revoked` integer, required
  - `authorizations_revoked` integer, required
  - `hitl_configs_without_approver` object[], required
    - `id` string, required
    - `name` string, nullable, required
    - `confirmations_denied` integer, required
  - `circles_repointed` integer, required: Phones only: circles that now reach the owner at `new_primary`; 0 for an email.
  - `new_primary` object, nullable, required: The row that becomes (or became) primary when the removed one was; null otherwise.
    - `id` string, required
    - `identifier` string, required: Masked.
  - `lookalike_watch` 'repointed' | 'canceled' | 'unchanged', required
  - `sessions_invalidated` integer, required: Active sessions signed out; the calling session stays. Idle devices are not counted, so read `sessions_signed_out` for whether every other device was signed out.
  - `sessions_signed_out` boolean, required: Every other device was signed out, idle ones included; the calling session stays. False when that could not be done — the removal itself still happened.
  - `notice` object[], required
    - `kind` 'email' | 'telegram' | 'whatsapp', required
    - `address` string, required: Masked.
    - `outcome` string, required: `sent`, `skipped:<why>` or `failed:<why>`. A notice is a courtesy after an act that already committed; a failed one never fails the request.

## Other responses

- `403`: `2fa_required` — a single-use step-up grant bound to this id is required (`reason: target_mismatch` when the grant names other ids); nothing was changed
- `404`: Phone not found
- `409`: `login_identifier`, `last_login_method` or `circles_need_phone` — a guard refused the removal; nothing was changed

---

[API](https://skmtc.dev/proof/apis/proof-holdings-api.md) · [All operations](https://skmtc.dev/proof/apis/proof-holdings-api/llms.txt) · [OpenAPI document](https://skmtc.dev/proof/apis/proof-holdings-api/revisions/b15f506de696?raw)
