# Renew a domain

> Renew safely: check first, understand the auto-renew and renew periods, and every reason a renewal can be refused.

Always call `/renew/check` first. It tells you whether the renewal will be accepted and whether a premium price applies, without charging anything.

:::danger[Important: a domain can only be renewed once per grace period]
This is the single most common reason a renewal is refused, and it surprises almost everyone the first time. **Nothing is wrong with the domain and nothing is wrong with your request — the registry is simply holding a window open during which a second renewal is not allowed.** These windows are temporary and they protect you financially: without them a domain could be renewed twice and you would be charged twice.

There are two such windows, and which one you hit depends on whether the domain had already expired.
:::

## After expiry: the auto-renew period

When a domain reaches its expiry date without being renewed, most registries do not delete it immediately. On the first day after expiry the registry **renews it automatically**, and the domain enters its **auto-renew grace period**.

Inside that window the domain has already been renewed once. A further renewal is refused until the window closes. The length varies by extension and is published as `autoRenewGracePeriod` in the TLD catalogue — commonly **two to three weeks**, and up to 45 days on some extensions.

| What you get | Meaning |
| --- | --- |
| `Dna.DomainService:Domain:10020` | "The domain is in its auto-renew period and its expiration has already been extended." |

:::tip[What to do]
**Nothing, usually.** The domain is already renewed — read `GET /api/v1/domains/info` and you will see the new `expirationDate`. Update your own records from it rather than retrying. If the customer genuinely needs an additional year on top, wait for the grace period to end and renew then.
:::

## Before expiry: the renew period

A domain that has *not* expired and that you renew normally enters a shorter window called the **renew period**, typically **three to five days**. A second renewal inside it is refused for the same reason.

| What you get | Meaning |
| --- | --- |
| `Dna.DomainService:Domain:10051` | "The domain has already been renewed and is currently in its renew-period. You can renew it again in a few days." |

:::note[Sometimes this resolves itself silently]
If the registry shows a later expiry than we hold on record, we take the registry's date, update the domain and return success without charging you again — the renewal you were asking for had already happened. You only get `10051` when the dates agree and the window is genuinely still open.
:::

## Renewing long before expiry

Most generic extensions do not let you renew at any time. If the domain's renewal date is more than **60 days** away, the renewal is refused:

| What you get | Meaning |
| --- | --- |
| `Dna.DomainService:Domain:10021` | "This domain cannot be renewed yet because its TLD does not support early renewal before the expiration date." |

The extensions that **do** allow it are mostly country-code domains — `.de` and `.it` are typical. The catalogue does not publish which extensions accept early renewal, so treat `Dna.DomainService:Domain:10021` as the answer: it means "not yet — try again once the domain is within 60 days of its renewal date". Inside that window, this rule no longer applies on any extension.

:::caution[One more limit when early renewal is allowed]
On extensions that accept early renewal, the time already remaining plus the term you are adding must not exceed the longest term the extension sells. Renewing a domain that still has 8 years left for another 5 is refused with `Dna.DomainService:Domain:1028` — "The maximum renewal period for the domain name has exceeded the allowed limit." Request fewer years.
:::

## All the reasons a renewal can be refused

| Code | Why, and what to do |
| --- | --- |
| `Dna.DomainService:Domain:10020` | **Auto-renew period.** Already renewed automatically after expiry. Call `GET /api/v1/domains/info` and store the new `expirationDate`; wait for the window to close if another year is really needed. |
| `Dna.DomainService:Domain:10051` | **Renew period.** Renewed within the last few days. Wait and retry. |
| `Dna.DomainService:Domain:10021` | **Too early.** More than 60 days out on an extension that does not allow early renewal. Retry once the domain is within 60 days of its renewal date. |
| `Dna.DomainService:Domain:1028` | **Too long.** The time remaining plus the requested term exceeds the longest term in the extension's `renewalPeriods` (usually 10 years), counted from today. Request fewer years. |
| `Dna.DomainService:Domain:10002` | The `period` you asked for is not one of the extension's `renewalPeriods`. Read them from the catalogue. |
| `Dna.DomainService:Domain:10022` | `period` is above 10. |
| `Dna.DomainService:Domain:10018` | The registry has a renewal prohibition on this domain, or its status does not allow renewal. |
| `Dna.DomainService:Domain:10045` | A `clientRenewProhibited` lock is set at the registry. |
| `Dna.DomainService:Domain:10019` | A registry connection problem was recorded for this domain in the last three days, so renewal is held back to avoid a double charge. Also returned when the request could not be completed for a temporary reason. Retry later. |

:::tip[The safe renewal routine]
1. `POST /api/v1/domains/renew/check` costs nothing from your balance. It catches a bad `period` (`1016`, `10022`, `10002`, returned as errors) and, with `renewabilityStatus: false`, three refusals in `errorMessageKey`: `10045` (renewal prohibited at the registry), `1016` (the term is too long; `/renew` reports the same case as `1028`) and `10071` (premium domain, 1 year only).
2. The check does **not** ask the registry about its renewal windows, so `10020` and `10051` only come back from `/renew` itself. When they do, call `GET /api/v1/domains/info` and sync `expirationDate` — the renewal you wanted has very likely already happened.
3. Otherwise renew, and store the `expirationDate` the response gives you rather than calculating it yourself.
:::

## POST /api/v1/domains/renew/check

Dry run: can this domain be renewed for this term, and at what price?

**Request**

```json
{
  "domainName": "apiname.com",
  "period": 1
}
```

**Response — renewable, standard price**

```json
{
  "renewabilityStatus": true,
  "renewalLock": false,
  "errorMessageKey": null,
  "isPremium": false,
  "premiumPrice": null,
  "premiumCurrency": null
}
```

**Response — not renewable**

```json
{
  "renewabilityStatus": false,
  "renewalLock": false,
  "errorMessageKey": "Dna.DomainService:Domain:1016",
  "isPremium": false,
  "premiumPrice": null,
  "premiumCurrency": null
}
```

**Response — premium domain**

```json
{
  "renewabilityStatus": true,
  "renewalLock": false,
  "errorMessageKey": null,
  "isPremium": true,
  "premiumPrice": 420.00,
  "premiumCurrency": "USD"
}
```

| Field | How to use it |
| --- | --- |
| `renewabilityStatus` | `true` means `/renew` will be accepted. Gate your renew button on this. |
| `renewalLock` | A renewal prohibition is set at the registry. |
| `errorMessageKey` | When `renewabilityStatus` is `false`, this is **the exact error code `/renew` would return**. Look it up in [Error codes](https://www.domainnameapi.com/docs/reference/errors/) and show the reason instead of letting the customer hit the error. |
| `premiumPrice` | Your selling price for **one year**. `null` when not premium, in which case the catalogue price applies. |

:::caution[Premium domains and multi-year renewal]
If you ask for more than one year on a premium domain, the response comes back with `renewabilityStatus: false` and `errorMessageKey: "Dna.DomainService:Domain:10071"`. Retry with `period: 1`.
:::

## POST /api/v1/domains/renew

Renews the domain and debits your balance.

**Request**

```json
{
  "domainName": "apiname.com",
  "period": 2
}
```

**Response — 200**

```json
{
  "success": true,
  "message": "Domain renewal successful",
  "domainId": "3c9a7e14-82b5-4d60-9f31-c7e8a05b6d42",
  "status": "Active",
  "expirationDate": "2029-10-30T12:04:17"
}
```

:::tip[What to do with it]
Store the new `expirationDate` — it is authoritative and comes from the registry. Do not calculate it yourself by adding years to the old date: grace periods and registry rounding mean the result is often different from what you would compute.
:::

:::note[Trustee domains]
If the domain uses our trustee service, the trustee fee is added to the same order automatically. You do not need to request it, and your balance is debited for both.
:::

**Errors**

| Code | Meaning and fix |
| --- | --- |
| `Dna.DomainService:Domain:1016` | Only on `/renew/check`: `period` is 0. (On `/renew`, a `period` below 1 is treated as 1.) |
| `Dna.DomainService:Domain:10007` | Domain not found or not yours. |
| `Dna.DomainService:Domain:10018` | Not in a renewable state — deleted, transferred out, or pending deletion. |
| `Dna.DomainService:Domain:10019` | Temporarily unavailable: a registry connection problem was recorded for this domain in the last three days. Retry later. |
| `Dna.DomainService:Domain:10020` | The registry already auto-renewed it; the expiry has moved. Call `GET /api/v1/domains/info` and store the new `expirationDate`. |
| `Dna.DomainService:Domain:10021` | Too early — this TLD does not allow renewal this far before expiry. |
| `Dna.DomainService:Domain:10051` | Renewed very recently and still inside the registry's renewal grace window. Wait a few days. |
| `Dna.DomainService:Domain:10022` | `period` above 10. |
| `Dna.DomainService:Domain:10002` | `period` is not one of the extension's `renewalPeriods`. |
| `Dna.DomainService:Domain:1028` | The renewal would push total registration past the longest term in the extension's `renewalPeriods` (usually 10 years from today). Renew for fewer years. |
| `Dna.DomainService:Domain:10045` | A renewal prohibition is set at the registry. |
| `Dna.DomainService:Domain:10071` | Premium domain, `period` above 1. |
| `Dna.DomainService:Domain:10072` | Premium price changed. Nothing charged — re-check and retry. |
| `Dna.DomainService:Domain:10049` | No renewal price configured. |
| `Dna.DomainService:Deposit:10001` | Insufficient balance. |
| `Dna.DomainService:Reseller:10001` | Balance suspended. |
| `Dna.DomainService:Trustee:10001` | Trustee domain with no trustee price configured. Open a ticket. |
| `Dna.DomainService:Domain:10059` | **Never retry.** Renewed at the registry, not recorded here. Open a support ticket with the domain name and your `X-Correlation-ID`. |
