# How to attach or remove a domain (https://developer.godaddy.com/en/docs/api-users/hosting/attach-domain)

---
title: How to attach or remove a domain
description: Attach a custom domain to your hosted app.
keywords: >-
  PUT /apps/{appId}/domains, custom domain, attach domain, DNS, domain
  configuration, hosting.domain:write
agentNotes:
  scopes:
    - 'hosting.domain:write'
  idempotent: false
  destructive: false
  failureRecovery: >-
    A 409 means the domain is already attached — treat as success. Otherwise
    verify you own the domain and it is not in use by another app.
related:
  guides:
    - title: Deploy your Node.js app
      href: /docs/api-users/hosting/workflows/deploy-nodejs-app
    - title: Manage apps
      href: /docs/api-users/hosting/manage-apps
    - title: Attach to a hosting plan
      href: /docs/api-users/hosting/attach-hosting-plan
  concepts:
    - title: Hosting concepts
      href: /docs/api-users/hosting/concepts
  apis:
    - title: Hosting API reference
      href: /docs/references/rest/hosting
---

## Overview

After you deploy your app, you can attach a custom domain to make it accessible through a friendly URL instead of the default hosting domain. Domain attachment is optional and your app is fully functional without it.

Only domains you own can be attached to your app. After attachment, traffic to that domain routes to your hosted application.

For the domain to route correctly to your app, your domain's DNS must point to GoDaddy's hosting infrastructure. If registered with GoDaddy, this is often automatic. For other registrars, update your domain's nameservers or DNS records accordingly.

Go to [Deploy your Node.js app](https://developer.godaddy.com/docs/api-users/hosting/workflows/deploy-nodejs-app) for the core deployment flow. Domain attachment happens after your app is live.

## Prerequisites

The following prerequisites are required before you can attach a domain to your app:

* a [Personal Access Token](https://developer.godaddy.com/personal-access-token) with the `hosting.domain:write` scope
* a deployed app

  Go to [Deploy your Node.js app](https://developer.godaddy.com/docs/api-users/hosting/workflows/deploy-nodejs-app) for more information on deploying an app.
* a domain you own (already registered with GoDaddy or another registrar)

## Attach a domain to an app

`POST /apps/{appId}/domains` attaches a domain to your app and initiates DNS verification. Returns `202 Accepted` with a domain attachment and enters DNS verification. DNS propagation can take a few minutes and your app is accessible at the domain after DNS resolves.

* Attach the domain:

  ```bash tab="curl"
  curl -s -X POST "$BASE_URL/v1/hosting/apps/$APP_ID/domains" \
    -H "Authorization: Bearer $GODADDY_PAT" \
    -H "Content-Type: application/json" \
    -d '{ "hostname": "my-app.example.com" }'
  ```

  ```js tab="Node"
  const res = await fetch(`${process.env.BASE_URL}/v1/hosting/apps/${appId}/domains`, {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${process.env.GODADDY_PAT}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ hostname: 'my-app.example.com' }),
  });

  if (!res.ok) {
    console.error(`Error: ${res.status}`);
    return;
  }

  const result = await res.json();
  console.log('Domain attachment initiated', result);
  ```

  ```python tab="Python"
  import requests, os

  resp = requests.post(
      f"{os.environ['BASE_URL']}/v1/hosting/apps/{app_id}/domains",
      headers={"Authorization": f"Bearer {os.environ['GODADDY_PAT']}"},
      json={"hostname": "my-app.example.com"},
  )

  if resp.status_code != 202:
      print(f"Error: {resp.status_code}")
      exit(1)

  result = resp.json()
  print("Domain attachment initiated", result)
  ```

  ```go tab="Go"
  body := strings.NewReader(`{"hostname":"my-app.example.com"}`)
  req, _ := http.NewRequest("POST",
      os.Getenv("BASE_URL")+"/v1/hosting/apps/"+appID+"/domains",
      body)
  req.Header.Set("Authorization", "Bearer "+os.Getenv("GODADDY_PAT"))
  req.Header.Set("Content-Type", "application/json")
  resp, _ := http.DefaultClient.Do(req)
  defer resp.Body.Close()

  if resp.StatusCode != 202 {
      fmt.Printf("Error: %d\n", resp.StatusCode)
      return
  }

  // decode resp.Body to get result
  var result map[string]interface{}
  json.NewDecoder(resp.Body).Decode(&result)
  fmt.Println("Domain attachment initiated", result)
  ```

## Remove a domain

To remove a domain attachment, use `DELETE /apps/{appId}/domains/{domainId}`. This detaches the domain from the app but does not modify DNS records at your registrar.

* Remove a domain:

  ```bash tab="curl"
  curl -s -X DELETE "$BASE_URL/v1/hosting/apps/$APP_ID/domains/$DOMAIN_ID" \
    -H "Authorization: Bearer $GODADDY_PAT"
  ```

  ```js tab="Node"
  const res = await fetch(`${process.env.BASE_URL}/v1/hosting/apps/${appId}/domains/${domainId}`, {
    method: 'DELETE',
    headers: { Authorization: `Bearer ${process.env.GODADDY_PAT}` },
  });
  ```

  ```python tab="Python"
  resp = requests.delete(
      f"{os.environ['BASE_URL']}/v1/hosting/apps/{app_id}/domains/{domain_id}",
      headers={"Authorization": f"Bearer {os.environ['GODADDY_PAT']}"},
  )
  ```

  ```go tab="Go"
  req, _ := http.NewRequest("DELETE",
      os.Getenv("BASE_URL")+"/v1/hosting/apps/"+appID+"/domains/"+domainID, nil)
  req.Header.Set("Authorization", "Bearer "+os.Getenv("GODADDY_PAT"))
  resp, _ := http.DefaultClient.Do(req)
  defer resp.Body.Close()
  ```

Success returns `204 No Content`.

## Common errors

The following table lists common errors when attaching a domain:

| Status | Cause                                    | Action                                                                                                   |
| ------ | ---------------------------------------- | -------------------------------------------------------------------------------------------------------- |
| `400`  | Invalid domain format                    | Verify the domain is a valid FQDN (e.g., `my-app.example.com`)                                           |
| `401`  | Expired or revoked PAT, or missing scope | Go to [Hosting core concepts](https://developer.godaddy.com/docs/api-users/hosting/concepts#scopes-reference) for the scopes you need |
| `404`  | App not found                            | Verify the app ID is correct                                                                             |
| `409`  | Domain already in use                    | The domain is already attached to this app or another app on your account                                |
