Manage DNS records
View as MarkdownManage DNS records and nameservers using the v3 API. Add, read, and delete individual DNS records, and replace authoritative nameservers with a single PUT request.
Overview
Create, read, and delete DNS records for domains hosted on GoDaddy's authoritative nameservers, and replace the authoritative nameservers themselves. All operations use the v3 API.
This page covers two related operations:
| Operation | Description |
|---|---|
| DNS records | Create and retrieve A, AAAA, CNAME, MX, TXT, SRV, NS, and CAA records on a domain hosted by GoDaddy's authoritative DNS. |
| Nameservers | Change which authoritative nameservers the registry returns for a domain. |
This page uses three OAuth scopes: domains.domain:read to list records, domains.dns:update to create and delete records, and domains.nameserver:update to replace nameservers. Go to Authentication for more information.
List DNS records
GET /v3/domains/zones/{zone}/dns-records returns a paginated collection of records for the zone. Use type and name query parameters to filter results.
The following procedure retrieves DNS records for a zone.
- Run the following command for your preferred language:
# All records
curl -s "https://api.godaddy.com/v3/domains/zones/example.com/dns-records" \
-H "Authorization: Bearer $GODADDY_PAT"
# Filter by type
curl -s "https://api.godaddy.com/v3/domains/zones/example.com/dns-records?type=A" \
-H "Authorization: Bearer $GODADDY_PAT"
# Filter by type and name
curl -s "https://api.godaddy.com/v3/domains/zones/example.com/dns-records?type=TXT&name=_acme-challenge" \
-H "Authorization: Bearer $GODADDY_PAT"const pat = process.env.GODADDY_PAT;
const zone = "example.com";
const url = new URL(`https://api.godaddy.com/v3/domains/zones/${zone}/dns-records`);
url.searchParams.set("type", "TXT");
url.searchParams.set("name", "_acme-challenge");
const res = await fetch(url, {
headers: { Authorization: `Bearer ${pat}` },
});
const records = await res.json();
console.log(records.items);import os, requests
pat = os.environ["GODADDY_PAT"]
zone = "example.com"
res = requests.get(
f"https://api.godaddy.com/v3/domains/zones/{zone}/dns-records",
params={"type": "TXT", "name": "_acme-challenge"},
headers={"Authorization": f"Bearer {pat}"},
)
res.raise_for_status()
for record in res.json()["items"]:
print(record["name"], record["type"], record["data"])package main
import (
"encoding/json"
"fmt"
"net/http"
"net/url"
"os"
)
func main() {
pat := os.Getenv("GODADDY_PAT")
zone := "example.com"
u, _ := url.Parse(fmt.Sprintf("https://api.godaddy.com/v3/domains/zones/%s/dns-records", zone))
q := u.Query()
q.Set("type", "TXT")
q.Set("name", "_acme-challenge")
u.RawQuery = q.Encode()
req, _ := http.NewRequest("GET", u.String(), nil)
req.Header.Set("Authorization", "Bearer "+pat)
res, err := http.DefaultClient.Do(req)
if err != nil { panic(err) }
defer res.Body.Close()
var body struct {
Items []map[string]any `json:"items"`
}
json.NewDecoder(res.Body).Decode(&body)
fmt.Println(body.Items)
}The response is a DNSRecords object with an items array of DNSRecord entries. Each record includes a recordId needed for delete operations. Go to the DNSRecord schema for the full field reference.
DNSRecord schema
Every entry in items[] is a DNSRecord object.
| Field | Required | Description | Note |
|---|---|---|---|
recordId | Read-only | Server-assigned stable identifier for the record. | |
name | Yes | Record name relative to the zone apex. | Use @ for the apex. Wildcards (*) supported for A, AAAA, and CNAME. |
type | Yes | Record type: A, AAAA, CNAME, MX, TXT, SRV, NS, CAA, ALIAS, or SOA (SOA is read-only). | |
data | Yes | Record value. | Format depends on type: IP for A/AAAA, hostname for CNAME, text for TXT, etc. |
ttl | Yes | Time-to-live in seconds. | Minimum 600 (10 min), maximum 86400 (24 hrs). |
priority | MX, SRV | Priority value. | Lower value equals higher preference. |
weight | SRV | Relative weight among equal-priority targets. | |
port | SRV | Target port number. | |
service | SRV | Service name. | Prefixed with an underscore (for example, _http). |
protocol | SRV | Transport protocol. | Prefixed with underscore (for example, _tcp). |
flag | CAA | Restriction flags byte. | Use 0 for non-critical, 128 for critical. |
tag | CAA | Property tag: issue, issuewild, or iodef. |
Pagination
Results are page-based. Use page (1-based, default 1) and pageSize (1–100, default 25) to navigate.
The following procedure paginates through DNS records.
- Navigate pages:
curl -s "https://api.godaddy.com/v3/domains/zones/example.com/dns-records?page=2&pageSize=50" \
-H "Authorization: Bearer $GODADDY_PAT"Add totalRequired=true to include totalItems and totalPages in the response — omitted by default to avoid count-query overhead on large zones. The response links array contains HATEOAS navigation links (self, first, last, next, prev) where applicable.
Add a record
POST /v3/domains/zones/{zone}/dns-records creates a single DNS record in the zone. Changes are applied synchronously — no polling required.
The following procedure adds a DNS record to a zone.
- Create a record:
curl -s -X POST "https://api.godaddy.com/v3/domains/zones/example.com/dns-records" \
-H "Authorization: Bearer $GODADDY_PAT" \
-H "Content-Type: application/json" \
-d '{ "type": "TXT", "name": "_acme-challenge", "data": "verification-string", "ttl": 600 }'const pat = process.env.GODADDY_PAT;
const zone = "example.com";
const res = await fetch(
`https://api.godaddy.com/v3/domains/zones/${zone}/dns-records`,
{
method: "POST",
headers: {
Authorization: `Bearer ${pat}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ type: "TXT", name: "_acme-challenge", data: "verification-string", ttl: 600 }),
},
);
const record = await res.json();
console.log("Created record", record.recordId);import os, requests
pat = os.environ["GODADDY_PAT"]
zone = "example.com"
res = requests.post(
f"https://api.godaddy.com/v3/domains/zones/{zone}/dns-records",
json={"type": "TXT", "name": "_acme-challenge", "data": "verification-string", "ttl": 600},
headers={
"Authorization": f"Bearer {pat}",
"Content-Type": "application/json",
},
)
res.raise_for_status()
print("Created record", res.json()["recordId"])package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"os"
)
func main() {
pat := os.Getenv("GODADDY_PAT")
zone := "example.com"
body := bytes.NewReader([]byte(
`{"type":"TXT","name":"_acme-challenge","data":"verification-string","ttl":600}`))
req, _ := http.NewRequest("POST",
fmt.Sprintf("https://api.godaddy.com/v3/domains/zones/%s/dns-records", zone), body)
req.Header.Set("Authorization", "Bearer "+pat)
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
var record struct{ RecordID string `json:"recordId"` }
json.NewDecoder(res.Body).Decode(&record)
fmt.Println("Created record", record.RecordID)
}A successful response returns 201 with the created DNSRecord in the body. The Location header contains the URL for the new record, with the recordId you'll need for deletes.
Not idempotent
Replaying a POST after a 5xx may create a duplicate record. Save the recordId from the Location header on success so you can clean up if needed. See Errors → Retry semantics.
Delete a record
DELETE /v3/domains/zones/{zone}/dns-records/{recordId} permanently removes a single record from the zone. Changes are applied synchronously.
The following procedure deletes a DNS record from a zone.
- Delete a record:
curl -s -X DELETE "https://api.godaddy.com/v3/domains/zones/example.com/dns-records/$RECORD_ID" \
-H "Authorization: Bearer $GODADDY_PAT"const pat = process.env.GODADDY_PAT;
const zone = "example.com";
const recordId = process.env.RECORD_ID;
const res = await fetch(
`https://api.godaddy.com/v3/domains/zones/${zone}/dns-records/${recordId}`,
{
method: "DELETE",
headers: { Authorization: `Bearer ${pat}` },
},
);
console.log(res.status); // expect 204import os, requests
pat = os.environ["GODADDY_PAT"]
zone = "example.com"
record_id = os.environ["RECORD_ID"]
res = requests.delete(
f"https://api.godaddy.com/v3/domains/zones/{zone}/dns-records/{record_id}",
headers={"Authorization": f"Bearer {pat}"},
)
print(res.status_code) # expect 204package main
import (
"fmt"
"net/http"
"os"
)
func main() {
pat := os.Getenv("GODADDY_PAT")
zone := "example.com"
recordID := os.Getenv("RECORD_ID")
req, _ := http.NewRequest("DELETE",
fmt.Sprintf("https://api.godaddy.com/v3/domains/zones/%s/dns-records/%s", zone, recordID), nil)
req.Header.Set("Authorization", "Bearer "+pat)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
fmt.Println(res.StatusCode) // expect 204
}A successful response returns 204 with no body.
Not idempotent
A 404 is returned if the recordId does not exist — deleting an already-deleted record is not a no-op. GoDaddy-managed SOA and NS records cannot be deleted; attempting to do so returns 409 Conflict.
Manage nameservers
PUT /v3/domains/domain-names/{domain-name}/nameservers replaces the authoritative nameservers for a domain. Accepts a plain array of 2–13 nameserver hostnames.
The following procedure replaces the authoritative nameservers for a domain.
- Replace a nameserver for a domain:
curl -s -X PUT "https://api.godaddy.com/v3/domains/domain-names/example.com/nameservers" \
-H "Authorization: Bearer $GODADDY_PAT" \
-H "Content-Type: application/json" \
-d '["ns1.example-dns.com", "ns2.example-dns.com"]'const pat = process.env.GODADDY_PAT;
const res = await fetch(
"https://api.godaddy.com/v3/domains/domain-names/example.com/nameservers",
{
method: "PUT",
headers: {
Authorization: `Bearer ${pat}`,
"Content-Type": "application/json",
},
body: JSON.stringify(["ns1.example-dns.com", "ns2.example-dns.com"]),
},
);
console.log(res.status); // expect 202import os, requests
res = requests.put(
"https://api.godaddy.com/v3/domains/domain-names/example.com/nameservers",
json=["ns1.example-dns.com", "ns2.example-dns.com"],
headers={
"Authorization": f"Bearer {os.environ['GODADDY_PAT']}",
"Content-Type": "application/json",
},
)
print(res.status_code) # expect 202package main
import (
"bytes"
"fmt"
"net/http"
"os"
)
func main() {
body := bytes.NewReader([]byte(`["ns1.example-dns.com","ns2.example-dns.com"]`))
req, _ := http.NewRequest("PUT",
"https://api.godaddy.com/v3/domains/domain-names/example.com/nameservers", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("GODADDY_PAT"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
fmt.Println(res.StatusCode) // expect 202
}A successful request returns 202 Accepted with a DomainOperation in the body and a Location header pointing to the operation URL. Propagation to the registry is asynchronous — poll the operation until it reaches a terminal state.
Authoritative DNS hand-off
Switching nameservers moves authoritative DNS off GoDaddy. Records you manage via /v3/domains/zones/{zone}/dns-records will no longer be served — make sure the new nameservers are fully configured before cutting over.
Use the CLI
After you set up the CLI, you can use it to list, add, replace, and delete DNS records on domains that use GoDaddy authoritative DNS.
The following procedure manages DNS records using the CLI.
- Run the command for your operation:
gddy dns list example.com
gddy dns list example.com --type A --name www
gddy dns add example.com --type A --name www --data 192.0.2.10 --ttl 600
gddy dns set example.com --type A --name www --data 192.0.2.20 --ttl 600
gddy dns delete example.com --type A --name wwwgddy dns add appends records. gddy dns set replaces every record for the type and name. gddy dns delete removes every record for the type and name; it does not delete GoDaddy-managed NS or SOA records. Use --dry-run with destructive commands when you want a preview.
Use the REST API for nameserver delegation; the CLI focuses on DNS record management.
Common errors
| Status | Most likely cause |
|---|---|
400 | Malformed request — missing required field, invalid field type, or unknown record type. Inspect fields[]. |
401 | Authentication credentials are missing or invalid. |
403 | Caller is not authorized. Check that your token includes the required scope (domains.dns:update or domains.nameserver:update). |
404 | Record or domain not found, or not owned by the authenticated account. |
409 | Conflict — request cannot be completed in the current state. For DNS: attempting to delete a GoDaddy-managed SOA or NS record (dns_record_not_mutable). |
422 | Valid structure but violates a business rule (e.g. CNAME at apex). |
429 | Rate limit exceeded. |
Full error envelope: Errors.
DNSRecord schema
| Field | Required | Description | Note |
|---|---|---|---|
recordId | Read-only | Server-assigned stable identifier for the record. | |
name | Yes | Record name relative to the zone apex. | Use @ for the apex. Wildcards (*) supported for A, AAAA, and CNAME. |
type | Yes | Record type: A, AAAA, CNAME, MX, TXT, SRV, NS, CAA, ALIAS, or SOA (SOA is read-only). | |
data | Yes | Record value. | Format depends on type (like IP for A/AAAA, hostname for CNAME, and text for TXT). |
ttl | Yes | Time-to-live in seconds. | Minimum 600 (10 min), maximum 86400 (24 hrs). |
priority | MX, SRV | Priority value. | Lower value equals higher preference. |
weight | SRV | Relative weight among equal-priority targets. | |
port | SRV | Target port number. | |
service | SRV | Service name. | Prefixed with an underscore (for example, _http). |
protocol | SRV | Transport protocol. | Prefixed with underscore (for example, _tcp). |
flag | CAA | Restriction flags byte. | Use 0 for non-critical, 128 for critical. |
tag | CAA | Property tag: issue, issuewild, or iodef. |
Reference
Next
Update contacts
Change registrant, admin, billing, or tech contacts.
Pagination
Walk paginated v1 list endpoints with limit and marker.
Agent & Automation Notes
domains.domain:read, domains.dns:update, domains.nameserver:updateRelated
API References
Concepts
Last updated on
How is this guide?