---
title: "Remove domain"
method: DELETE
path: "/api/v1/me/domains/{id}"
tags: ["Domains"]
---

# Remove domain

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

## Request

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

Remove a domain from the account (h-implement-proper-deletion, DOM-2). Runs the whole-domain cascade first — every proof of the domain and every delegation issued from it are revoked — then deletes the row and its saved provider credentials, drops the cached artifact claims, and cleans up outside the account best-effort: our `_proof` TXT record at the DNS provider (only with a saved credential, by exact name and value) and the Resend sending domain (unless another account still uses it). What stays and why is listed in `external.leftovers`; a cleanup failure never fails the removal. Requires a single-use `domain_remove` step-up grant bound to this id (`403 2fa_required`; `reason: target_mismatch` when the grant names other ids). A notice goes to the owner. Cannot be undone — to use the domain again, add it and verify it afresh. With an API key, use `DELETE /verifications/domain/{id}`, which refuses a verified domain.

## Path parameters

- `id` string, required: MongoDB ObjectId

## Response `200`

Domain removed — what was revoked, what was cleaned up, what stays

- DomainRemovedResponse
  - `success` true, required
  - `domain` string, required
  - `proofs_revoked` integer, required
  - `delegations_revoked` object[], required
    - `proof_id` string, required
    - `delegate` string, required
    - `delegate_type` string, required
    - `principal` string, required
  - `external` object, required
    - `txt_record` 'removed' | 'kept' | 'not_attempted', required: Our `_proof` TXT record at the DNS provider — removed only with a saved credential, by exact name AND value.
    - `resend_domain` 'removed' | 'kept' | 'shared' | 'not_attempted', required: The Resend sending domain — `shared` when another account still uses it.
    - `cleaned_up` string[], required: Human sentences: what we removed for the owner.
    - `leftovers` string[], required: Human sentences: what stays in place and why (we cannot remove it).
  - `carriers` object[], required: Where the revoked delegations are still published (the `_mcp.<domain>` pointer, a delegate card) — bounded to a few delegations and a few seconds.
    - `delegation` string, required: The revoked delegation, by delegate.
    - `rows` object[], required
      - `carrier` 'dns_pointer' | 'delegate_card', required
      - `state` string, required
      - `reason` string, required
      - `cardUrl` string
  - `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 `domain_remove` grant bound to this id is required (`reason: target_mismatch` when the grant names other ids); nothing was changed
- `404`: Domain 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/6b8d61ee354f?raw)
