# remove_custom_domain

Source: https://modulify.ai/docs/api/domains/remove-custom-domain

Removes one custom domain from a site, deleting the domain and its TLS certificate.

- Title: Remove a custom domain
- Scope: `config:write`
- Access: Destructive
- Endpoint: `POST /v1/remove_custom_domain`

The site stops answering on that hostname immediately, anyone following an old link to it lands nowhere, and reconnecting it later means adding it again and waiting for a fresh certificate. The tool tells the client to always confirm with you first.

The site's other domains keep working, and a verification pending through `start_domain_verification` is not touched. If this domain has a www companion, the companion is promoted into this domain's place rather than deleted, so read the returned `domains` to see what the site answers on now. Only this domain's own companion is promoted, never another domain's.

The primary domain, the one links to the live site use, is worked out again from what remains. It needs the **Manage domains** permission in the workspace. See [Replacing or removing a domain](https://modulify.ai/docs/publish/custom-domains#replacing-or-removing-a-domain).

## Request

Call it with a `POST` to `https://api.modulify.ai/v1/remove_custom_domain`, sending the inputs below as a JSON object. The token needs the `config:write` scope.

> **Warning**
>
> This method is marked destructive: it deletes or overwrites data. Check the inputs before you call it, and send an [Idempotency-Key](https://modulify.ai/docs/api/idempotency) header whenever you might retry it.

```bash
curl -X POST https://api.modulify.ai/v1/remove_custom_domain \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"projectId":"PROJECT_ID","workspaceId":"WORKSPACE_ID","domainId":"DOMAIN_ID"}'
```

Over MCP, the same method is the [remove_custom_domain tool](https://modulify.ai/docs/mcp/domains/remove-custom-domain).

## Inputs

| Input | Type | Required | Description |
| --- | --- | --- | --- |
| `projectId` | string | Yes | The site id. |
| `workspaceId` | string | Yes | The workspace the site belongs to. |
| `domainId` | string | Yes | The `_id` of the custom domain to remove, as `get_domain_status` or `add_custom_domain` returned it. |

## Response

Every call answers with the [JSON envelope](https://modulify.ai/docs/api/requests-and-responses#the-response) of `success`, `message`, `data`, `code` and `version`. `data` holds the result described above, and on a method that returns a total, `count` carries it. The [response headers](https://modulify.ai/docs/api/requests-and-responses#headers-on-every-method-call) carry the call's `X-Request-Id` and what is left of your per-minute budget in `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `X-RateLimit-Reset`. [Errors](https://modulify.ai/docs/api/errors) explains every status code a call can answer with.