Support
DomainsManage Domains

Manage renewals

View as Markdown

Toggle auto-renew and manually renew a domain before expiration.

Overview

Control when and how a domain renews using two mechanisms: auto-renew (a flag that fires before expiration) and manual renewal (a POST call that extends registration immediately and charges the account). Use auto-renew for domains you want to keep without manual intervention; use manual renewal to extend a domain ahead of an upcoming expiration.

Renewal management isn't available in v3 yet. This page uses the v1 endpoints (POST /v1/domains/{domain}/renew and PATCH /v1/domains/{domain}).

A domain's renewal state is controlled through two mechanisms:

  • Auto-renew — a flag on the domain that tells the registrar to renew automatically before expiration. Free to toggle. No registry interaction until the renewal actually fires.
  • Manual renew — a POST /v1/domains/{domain}/renew call that adds a registration period immediately. Charges the account in production.

Both the renewAuto flag and the expires timestamp live on the DomainDetail object.

Read renewal state

Returns the full DomainDetail object. The renewAuto flag and expires timestamp are the two renewal-relevant fields.

The following procedure reads the renewal state for a domain.

  • Run the following command:
curl -s "https://api.godaddy.com/v1/domains/example.com" \
  -H "Authorization: Bearer $GODADDY_PAT" \
  -H "Accept: application/json"
{
  "domain": "example.com",
  "status": "ACTIVE",
  "renewAuto": true,
  "expires": "2026-03-15T00:00:00.000Z"
}

Toggle auto-renew

Auto-renew is toggled through PATCH /v1/domains/{domain}.

The following procedure toggles auto-renew on a domain.

Enable auto-renew:

  • Run the following command for your preferred language:
curl -s -X PATCH "https://api.godaddy.com/v1/domains/example.com" \
  -H "Authorization: Bearer $GODADDY_PAT" \
  -H "Content-Type: application/json" \
  -d '{"renewAuto": true}'
const pat = process.env.GODADDY_PAT;
const res = await fetch("https://api.godaddy.com/v1/domains/example.com", {
  method: "PATCH",
  headers: {
    Authorization: `Bearer ${pat}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ renewAuto: true }),
});
console.log(res.status); // expect 204
import os, requests

res = requests.patch(
    "https://api.godaddy.com/v1/domains/example.com",
    json={"renewAuto": True},
    headers={
        "Authorization": f"Bearer {os.environ['GODADDY_PAT']}",
        "Content-Type": "application/json",
    },
)
print(res.status_code)  # expect 204
package main

import (
    "bytes"
    "fmt"
    "net/http"
    "os"
)

func main() {
    body := bytes.NewReader([]byte(`{"renewAuto": true}`))
    req, _ := http.NewRequest("PATCH",
        "https://api.godaddy.com/v1/domains/example.com", 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 204
}

Disable auto-renew:

  • Run the following command:
curl -s -X PATCH "https://api.godaddy.com/v1/domains/example.com" \
  -H "Authorization: Bearer $GODADDY_PAT" \
  -H "Content-Type: application/json" \
  -d '{"renewAuto": false}'

Both return 204 No Content. The operation is free and idempotent — setting the flag to its current value is a no-op.

Auto-renew is enabled by default at registration time. If you are managing domains on behalf of customers, consider whether you want the domain to auto-renew without explicit confirmation.

Manually renew a domain

POST /v1/domains/{domain}/renew appends a registration period to the current expiration date.

The following procedure manually renews a domain.

  • Run the following command for your preferred language:
curl -s -X POST "https://api.godaddy.com/v1/domains/example.com/renew" \
  -H "Authorization: Bearer $GODADDY_PAT" \
  -H "Content-Type: application/json" \
  -d '{"period": 1}'
const pat = process.env.GODADDY_PAT;
const res = await fetch("https://api.godaddy.com/v1/domains/example.com/renew", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${pat}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ period: 1 }),
});
if (!res.ok) throw new Error(`Renewal failed: ${res.status}`);
const order = await res.json();
console.log("Order:", order.orderId, "Total:", order.total / 1_000_000, order.currency);
import os, requests

res = requests.post(
    "https://api.godaddy.com/v1/domains/example.com/renew",
    json={"period": 1},
    headers={
        "Authorization": f"Bearer {os.environ['GODADDY_PAT']}",
        "Content-Type": "application/json",
    },
)
res.raise_for_status()
order = res.json()
print("Order:", order["orderId"], "Total:", order["total"] / 1_000_000, order["currency"])
package main

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

func main() {
    body := bytes.NewReader([]byte(`{"period": 1}`))
    req, _ := http.NewRequest("POST",
        "https://api.godaddy.com/v1/domains/example.com/renew", 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 order struct {
        OrderID  int    `json:"orderId"`
        Total    int    `json:"total"`
        Currency string `json:"currency"`
    }
    json.NewDecoder(res.Body).Decode(&order)
    fmt.Printf("Order: %d  Total: %.2f %s\n",
        order.OrderID, float64(order.Total)/1_000_000, order.Currency)
}

Response:

{
  "orderId": 8675309,
  "itemCount": 1,
  "total": 1199000,
  "currency": "USD"
}

total is in currency-micro-unit format — divide by 1,000,000 to get the value in currency.

Request body

FieldRequiredDescription
periodNoYears to add (1–10). Defaults to the period specified at original registration.

Renewal charges real money

POST /v1/domains/{domain}/renew charges the account's billing method. Verify the domain name, period, and price before sending. To check the renewal price first, call the v2 domain detail endpoint:

curl -s "https://api.godaddy.com/v2/customers/{customerId}/domains/example.com" \
  -H "Authorization: Bearer $GODADDY_PAT" \
  -H "Content-Type: application/json"

The response includes a renewal object with the current price:

{
  "renewal": {
    "currency": "USD",
    "price": 11990000,
    "renewable": true
  }
}

price is in currency-micro-unit format — divide by 1,000,000 for the currency value (for example, 11990000 = $11.99).

Response: DomainPurchaseResponse

FieldDescription
orderIdUnique identifier of the order.
itemCountNumber of items in the order (typically 1).
totalTotal cost in currency-micro-unit format. Divide by 1,000,000 for the currency value.
currencyISO 4217 currency code (e.g. USD).

Expiration and grace periods

After a domain expires, GoDaddy provides a recovery window before the domain is permanently released. Standard renewal pricing applies for approximately 12 days post-expiration. After that, the domain leaves your account and additional fees apply to recover it.

Grace periods vary by TLD

ccTLDs and some other TLDs follow different expiration timelines. Check the full timeline before relying on these windows in your logic.

Go to Standard domain expiration timeline for the complete day-by-day expiration timeline.

Common errors

StatusMost likely cause
400Malformed request body or invalid period value.
403Credential lacks write access to this domain.
404Domain doesn't exist or isn't owned by the authenticated account.
409Domain status prevents renewal (e.g. domain is in a transfer in progress).
422Period exceeds the TLD maximum or would push total registration past the registry limit.

Full error envelope: Errors.

Reference

Next

Agent & Automation Notes

PermissionsDomain Owner, Billing
Scopesdomains.domain:read, domains.domain:update
Rate limitRate-limited per credential per window. Go to /docs/api-users/rate-limits for current values.
IdempotentNo
DestructiveNo
On failurerenewAuto toggle is idempotent. Manual renew is NOT — charging the account is a real-money side effect. On timeout/network error, GET the domain to verify the new expires timestamp before retrying.

Last updated on

How is this guide?

On this page