# End-to-end workflow (https://developer.godaddy.com/en/docs/api-users/full-workflow)

***

title: End-to-end workflow
description: Complete workflow for buying and configuring a domain — search, quote, register, add DNS, verify. Runnable start-to-finish in under 5 minutes.
agentNotes:
permissions: \["Payment Profile", "DNS Management"]
scopes: \["domains.domain:read", "domains.registration:write", "domains.dns:update"]
idempotent: false
destructive: true
failureRecovery: "Registration is NOT idempotent without Idempotency-Key header. On any partial success, GET the domain first before retrying. Real money changes hands — be sure you want to do this before executing."
related:
guides:

* title: "Quickstart"
  href: "/docs/api-users/quickstart"
* title: "Search domain availability"
  href: "/docs/api-users/search-domains"
* title: "Register a domain"
  href: "/docs/api-users/purchase-domains/register"
* title: "Manage DNS records"
  href: "/docs/api-users/manage-domains/dns"
  concepts:
* title: "Authentication"
  href: "/docs/api-users/auth"
* title: "Handle errors"
  href: "/docs/api-users/errors"
* title: "Rate limits"
  href: "/docs/api-users/rate-limits"

***

A complete end-to-end workflow: search for an available domain, lock a price with a quote, register it (with idempotency for retry safety), add a DNS record, and verify. Every step is copy-paste runnable in curl, Node, Python, or Go.

## Overview

**Prerequisites**: a GoDaddy account with a payment method on file, a [Personal Access Token](https://developer.godaddy.com/docs/api-users/auth) with `domains.domain:read`, `domains.registration:write`, and `domains.dns:update` scopes, and the CLI or curl. Export the token:

```bash
export GODADDY_PAT="<YOUR_TOKEN>"
export BASE="https://api.godaddy.com"
```

## Check availability

`GET /v3/domains/check-availability` returns availability and indicative pricing for a domain.

```bash tab="curl"
curl -s "$BASE/v3/domains/check-availability?domain=example.com" \
  -H "Authorization: Bearer $GODADDY_PAT"
```

```js tab="Node"
const res = await fetch(`${process.env.BASE}/v3/domains/check-availability?domain=example.com`, {
  headers: { Authorization: `Bearer ${process.env.GODADDY_PAT}` },
});
const { available, prices } = await res.json();
if (!available) throw new Error("Domain not available");
console.log("Available at", prices[0].price.value / 100, prices[0].price.currencyCode);
```

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

res = requests.get(
    f"{os.environ['BASE']}/v3/domains/check-availability",
    params={"domain": "example.com"},
    headers={"Authorization": f"Bearer {os.environ['GODADDY_PAT']}"},
)
data = res.json()
assert data["available"], "Domain not available"
price = data["prices"][0]["price"]
print(f"Available at {price['value'] / 100} {price['currencyCode']}")
```

```go tab="Go"
package main

import (
    "encoding/json"
    "fmt"
    "net/http"
    "os"
)

type Price struct {
    Value        int    `json:"value"`
    CurrencyCode string `json:"currencyCode"`
}

func main() {
    req, _ := http.NewRequest("GET",
        os.Getenv("BASE")+"/v3/domains/check-availability?domain=example.com", nil)
    req.Header.Set("Authorization", "Bearer "+os.Getenv("GODADDY_PAT"))
    res, _ := http.DefaultClient.Do(req)
    defer res.Body.Close()

    var data struct {
        Available bool `json:"available"`
        Prices    []struct{ Price Price } `json:"prices"`
    }
    json.NewDecoder(res.Body).Decode(&data)
    if !data.Available { panic("not available") }
    fmt.Printf("Available at %d %s\n", data.Prices[0].Price.Value/100, data.Prices[0].Price.CurrencyCode)
}
```

Response shape:

```json
{
  "domain": "example.com",
  "available": true,
  "prices": [
    { "term": "YEAR", "period": 1, "price": { "currencyCode": "USD", "value": 1199 } }
  ]
}
```

## Get a registration quote

`POST /v3/domains/registration-quotes` locks the price. The returned `quoteToken` guarantees the price you see is the price you'll pay when you execute registration.

```bash tab="curl"
curl -s -X POST "$BASE/v3/domains/registration-quotes" \
  -H "Authorization: Bearer $GODADDY_PAT" \
  -H "Content-Type: application/json" \
  -d '{"domain": "example.com", "period": 1}'
```

```js tab="Node"
const res = await fetch(`${process.env.BASE}/v3/domains/registration-quotes`, {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.GODADDY_PAT}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ domain: "example.com", period: 1 }),
});
const { quoteToken, expiresAt } = await res.json();
console.log("Quote locked until", expiresAt);
```

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

res = requests.post(
    f"{os.environ['BASE']}/v3/domains/registration-quotes",
    json={"domain": "example.com", "period": 1},
    headers={
        "Authorization": f"Bearer {os.environ['GODADDY_PAT']}",
        "Content-Type": "application/json",
    },
)
quote = res.json()
print("Quote locked until", quote["expiresAt"])
```

```go tab="Go"
body := strings.NewReader(`{"domain": "example.com", "period": 1}`)
req, _ := http.NewRequest("POST",
    os.Getenv("BASE")+"/v3/domains/registration-quotes", 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()

var quote struct {
    QuoteToken string `json:"quoteToken"`
    ExpiresAt  string `json:"expiresAt"`
}
json.NewDecoder(res.Body).Decode(&quote)
fmt.Println("Quote locked until", quote.ExpiresAt)
```

## Register the domain

`POST /v3/domains/registrations` executes the registration. Send an `Idempotency-Key` header — if the request times out or returns 5xx, replay with the same key and the server dedupes.

This call charges the account's payment profile. Verify the domain name and quoted price before executing.

```bash tab="curl"
curl -s -X POST "$BASE/v3/domains/registrations" \
  -H "Authorization: Bearer $GODADDY_PAT" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "quoteToken": "qt_abc123...",
    "domain": "example.com",
    "period": 1,
    "consent": {
      "agreedAt": "2026-07-07T10:30:00.000Z",
      "agreementTypes": ["API_DPA"]
    }
  }'
```

```js tab="Node"
import { randomUUID } from "node:crypto";

const res = await fetch(`${process.env.BASE}/v3/domains/registrations`, {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.GODADDY_PAT}`,
    "Content-Type": "application/json",
    "Idempotency-Key": randomUUID(),
  },
  body: JSON.stringify({
    quoteToken: "qt_abc123...",
    domain: "example.com",
    period: 1,
    consent: {
      agreedAt: new Date().toISOString(),
      agreementTypes: ["API_DPA"]
    },
  }),
});
if (res.status !== 201) throw new Error(`Registration failed: ${res.status}`);
console.log("Registered:", (await res.json()).domain);
```

```python tab="Python"
import os, uuid, requests
from datetime import datetime, timezone

res = requests.post(
    f"{os.environ['BASE']}/v3/domains/registrations",
    json={
        "quoteToken": "qt_abc123...",
        "domain": "example.com",
        "period": 1,
        "consent": {
            "agreedAt": datetime.now(timezone.utc).isoformat(),
            "agreementTypes": ["API_DPA"]
        },
    },
    headers={
        "Authorization": f"Bearer {os.environ['GODADDY_PAT']}",
        "Content-Type": "application/json",
        "Idempotency-Key": str(uuid.uuid4()),
    },
)
res.raise_for_status()
print("Registered:", res.json()["domain"])
```

```go tab="Go"
import "github.com/google/uuid"

body := map[string]any{
    "quoteToken": "qt_abc123...",
    "domain":     "example.com",
    "period":     1,
    "consent": map[string]any{
        "agreedAt":       time.Now().UTC().Format(time.RFC3339),
        "agreementTypes": []string{"API_DPA"},
    },
}
b, _ := json.Marshal(body)
req, _ := http.NewRequest("POST",
    os.Getenv("BASE")+"/v3/domains/registrations", bytes.NewReader(b))
req.Header.Set("Authorization", "Bearer "+os.Getenv("GODADDY_PAT"))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Idempotency-Key", uuid.NewString())

res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
if res.StatusCode != 201 { panic(fmt.Sprint("registration failed: ", res.StatusCode)) }
```

Returns `201 Created` with the order ID and domain metadata.

## Add a DNS record

`POST /v3/domains/zones/{zone}/dns-records` adds a record. Common first step: an A record pointing the apex at your web server.

```bash tab="curl"
curl -s -X POST "$BASE/v3/domains/zones/example.com/dns-records" \
  -H "Authorization: Bearer $GODADDY_PAT" \
  -H "Content-Type: application/json" \
  -d '{"type": "A", "name": "@", "data": "192.0.2.1", "ttl": 600}'
```

```js tab="Node"
const res = await fetch(
  `${process.env.BASE}/v3/domains/zones/example.com/dns-records`,
  {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.GODADDY_PAT}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ type: "A", name: "@", data: "192.0.2.1", ttl: 600 }),
  },
);
const record = await res.json();
console.log("Created record", record.recordId);
```

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

res = requests.post(
    f"{os.environ['BASE']}/v3/domains/zones/example.com/dns-records",
    json={"type": "A", "name": "@", "data": "192.0.2.1", "ttl": 600},
    headers={
        "Authorization": f"Bearer {os.environ['GODADDY_PAT']}",
        "Content-Type": "application/json",
    },
)
res.raise_for_status()
print("Created record", res.json()["recordId"])
```

```go tab="Go"
body := strings.NewReader(`{"type": "A", "name": "@", "data": "192.0.2.1", "ttl": 600}`)
req, _ := http.NewRequest("POST",
    os.Getenv("BASE")+"/v3/domains/zones/example.com/dns-records", 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()
```

## Verify propagation

Confirm the record was accepted by the API, then confirm it's answering at a public resolver.

1. Read the zone back through the API. The new record should appear in `items[]`.

   ```bash
   curl -s "$BASE/v3/domains/zones/example.com/dns-records?type=A" \
     -H "Authorization: Bearer $GODADDY_PAT"
   ```

2. Query a public resolver. Global propagation completes within seconds; the delay end-users see depends on their local resolver's TTL cache.

   ```bash
   dig +short A example.com
   # 192.0.2.1
   ```

## What's next

* Add more DNS records (CNAME, MX, TXT) via the same endpoint — see the [DNS how-to](https://developer.godaddy.com/docs/api-users/manage-domains/dns)
* Set up domain forwarding to redirect apex-www or subdomains — see [Forwarding](https://developer.godaddy.com/docs/api-users/manage-domains/forwarding)
* Manage renewals and auto-renew — see [Renewals](https://developer.godaddy.com/docs/api-users/manage-domains/renewals)
* Lock the domain against unauthorized transfer — see [Registry lock](https://developer.godaddy.com/docs/api-users/manage-domains/lock)
