# Manage renewals (https://developer.godaddy.com/en/docs/api-users/manage-domains/renewals)



## 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.

<Callout type="info">
  Renewal management isn't available in v3 yet. This page uses the v1 endpoints (`POST /v1/domains/{domain}/renew` and `PATCH /v1/domains/{domain}`).
</Callout>

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:

```bash
curl -s "https://api.godaddy.com/v1/domains/example.com" \
  -H "Authorization: Bearer $GODADDY_PAT" \
  -H "Accept: application/json"
```

```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:

<Tabs items={['curl', 'Node', 'Python', 'Go']}>
  <>
    <Tab value="curl">
      ```bash
      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}'
      ```
    </Tab>

    <Tab value="Node">
      ```js
      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
      ```
    </Tab>

    <Tab value="Python">
      ```python
      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
      ```
    </Tab>

    <Tab value="Go">
      ```go
      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
      }
      ```
    </Tab>
  </>
</Tabs>

**Disable auto-renew:**

* Run the following command:

```bash
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.

<Callout type="info">
  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.
</Callout>

## 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:

<Tabs items={['curl', 'Node', 'Python', 'Go']}>
  <>
    <Tab value="curl">
      ```bash
      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}'
      ```
    </Tab>

    <Tab value="Node">
      ```js
      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);
      ```
    </Tab>

    <Tab value="Python">
      ```python
      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"])
      ```
    </Tab>

    <Tab value="Go">
      ```go
      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)
      }
      ```
    </Tab>
  </>
</Tabs>

Response:

```json
{
  "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

| Field    | Required | Description                                                                     |
| -------- | -------- | ------------------------------------------------------------------------------- |
| `period` | No       | Years to add (1–10). Defaults to the period specified at original registration. |

<Callout type="warning" title="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:

  ```bash
  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:

  ```json
  {
    "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`).
</Callout>

### Response: DomainPurchaseResponse

| Field       | Description                                                                             |
| ----------- | --------------------------------------------------------------------------------------- |
| `orderId`   | Unique identifier of the order.                                                         |
| `itemCount` | Number of items in the order (typically 1).                                             |
| `total`     | Total cost in `currency-micro-unit` format. Divide by 1,000,000 for the currency value. |
| `currency`  | ISO 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.

<Callout type="warning" title="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.
</Callout>

Go to [Standard domain expiration timeline](https://www.godaddy.com/help/standard-domain-expiration-timeline-609) for the complete day-by-day expiration timeline.

## Common errors

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

Full error envelope: [Errors](https://developer.godaddy.com/docs/api-users/errors).

## Reference

* [v1 domain settings — `PATCH /v1/domains/{domain}` (auto-renew toggle)](https://developer.godaddy.com/docs/references/rest/domains/v1/manage-domain-settings)
* [v1 registration and renewals — `POST /v1/domains/{domain}/renew`](https://developer.godaddy.com/docs/references/rest/domains/v1/register-and-renew-domains)

## Next

<Cards>
  <Card title="Registry lock" description="Lock or unlock the transfer-lock flag on a domain." href="/docs/api-users/manage-domains/lock" />
</Cards>
