---
title: "Revoke asset"
method: DELETE
path: "/api/v1/me/assets/{id}"
tags: ["Assets"]
---

# Revoke asset

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

## Request

- Base URL: `https://api.proof.holdings`
- URL: `https://api.proof.holdings/api/v1/me/assets/{id}`
- Auth: one of:
  - HTTP bearer
  - API key in cookie `auth_token`

Revoke one asset's proofs. Revoking withdraws PROOFS, not the identifier: a phone or email row stays active (signing in with it again issues a new proof). Revoking one asset of a phone or email revokes every asset of that identifier. Revoking a DOMAIN asset runs the whole-domain cascade: every proof of the domain and every delegation issued from it are revoked, and the domain is demoted to `reverification_required` with its DNS challenge rotated. Cannot be undone. Owner only: an API key answers `403 owner_session_required` for every asset type (revoke the proof itself with `POST /proofs/{id}/revoke` instead). A session needs a single-use `revocation_bulk` step-up grant bound to exactly the ids it sends (`403 2fa_required`; `reason: target_mismatch` when the grant names other ids). A notice goes to the owner. An already-revoked asset answers 200 with nothing revoked and spends no grant.

## Path parameters

- `id` string, required: MongoDB ObjectId

## Response `200`

Revoked (or already revoked — `outcome` says which)

- object
  - `asset_id` string, required
  - `outcome` 'revoked' | 'already_revoked' | 'not_found', required: `not_found` is also the answer for an asset the account does not own.
  - `type` 'phone' | 'email' | 'domain' | 'social' | 'wallet' | 'telegram_bot'
  - `identifier` string: Masked for phones and emails; a domain travels in clear.
  - `revoked_asset_ids` string[]: Every asset of the same identifier this call revoked with it, the named one included — a phone holds one asset per channel, a domain one per verification.
  - `delegations_revoked` object[]: Domains only: the delegations revoked with the proofs. Re-verifying does not bring them back.
    - `proof_id` string, required
    - `delegate` string, required
    - `delegate_type` string, required
    - `principal` string, required
  - `domain_status` 'pending' | 'verifying' | 'verified' | 'failed' | 'expired' | 'revoking' | 'reverification_required' | 'null', nullable: Domains only: `reverification_required` — the domain stays on the account and needs re-verification before anything can be issued from it.
  - `success` true, required
  - `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`: `owner_session_required` — an API key may not revoke through this route (any asset type, any proof state); `2fa_required` — a session needs a `revocation_bulk` grant bound to this id (`reason: target_mismatch` when the grant names other ids). Nothing was changed
- `404`: Asset not found
- `409`: `domain_revoking` — a revocation of this domain is already running; nothing was changed and no step-up code was spent. Retry in a moment

---

[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)
