Support
Register a domainRegister a domain

Register a domain

View as Markdown

Register a domain using the GoDaddy Domains API.

Overview

This guide covers registering a domain programmatically using the GoDaddy Domains API.

Registration charges the account's billing method and isn't reversible. Make sure you have a payment method on file before registering.

WHOIS accuracy

ICANN requires that registrant contact information be accurate. Providing false contact information can result in domain suspension. Use WHOIS privacy after registration if you want to protect your contact details. Don't enter fake data.

Prerequisites

  • a GoDaddy account with a payment method on file

    Note

    Go to Create account to create a GoDaddy account and add or update payment methods.

  • a PAT with domains.domain:create scope
  • a registrant contact with name, email, phone, and mailing address
  • a confirmed available domain
  • (optional) the GoDaddy CLI installed and configured

Register a domain

v3 separates pricing from execution. You get a price quote first, locking a quoteToken, then execute the registration with that token. This ensures the price you agreed to is the price charged. Always poll at least once even if the initial response appears synchronous.

Note

v3 does not accept inline payment or registrant contact overrides. The billing method and registrant contact are resolved from the account profile. If the account is missing a payment method or required contact fields, the quote returns 422 with field-level details.

Check availability

Confirm the domain is available before quoting.

  • Run the availability check:

    curl -s "https://api.godaddy.com/v3/domains/check-availability?domain=example.com" \
      -H "Authorization: Bearer $GODADDY_PAT"

Note

Go to Search availability for bulk checks and suggestions.

Get a registration quote

POST /v3/domains/registration-quotes locks the price and returns the requiredAgreements list you need for the next step. The quoteToken guarantees the price you see is the price charged at registration.

  • Get a quote:

    curl -s -X POST "https://api.godaddy.com/v3/domains/registration-quotes" \
      -H "Authorization: Bearer $GODADDY_PAT" \
      -H "Content-Type: application/json" \
      -d '{"domain": "example.com", "period": 1}'
    {
      "quoteToken": "qt_abc123...",
      "expiresAt": "2026-01-15T10:45:00.000Z",
      "requiredAgreements": [
        {
          "agreementType": "API_DPA",
          "title": "API Domain Purchase Agreement",
          "url": "https://www.godaddy.com/agreements/showdoc?pageid=reg_sa"
        }
      ],
      "items": [
        {
          "domain": "example.com",
          "period": 1,
          "price": {
            "currencyCode": "USD",
            "value": 1199
          }
        }
      ]
    }

Note

price.value is in minor currency units — cents for USD, so 1199 = $11.99. Divide by 100 for display.

Note

The quoteToken expires after a short window. If it expires before you execute, fetch a new quote.

Review the required agreements

The quote response includes a requiredAgreements list (the legal agreements you need to review before you submit the registration). Each item has a title for display and a url linking to the full legal text.

  1. Display each agreement to the user:

    for (const agreement of requiredAgreements) {
      console.log(`Review: ${agreement.title}`);
      console.log(`Full text: ${agreement.url}`);
    }
  2. After the user confirms, capture the agreement types and consent timestamp:

    const agreedAt = new Date().toISOString();
    const agreedTypes = requiredAgreements.map((a) => a.agreementType);

ICANN compliance

Use the actual timestamp of when the user clicked accept for agreedAt — not the time of the API call. Synthetic timestamps violate ICANN policy.

Agreements vary by TLD

Required agreements depend on the TLD. .ca domains require a CIRA agreement, .au domains require an AURA agreement. Always use the agreementType values from requiredAgreements — don't hardcode them.

Submit the registration

Send the quoteToken and consent to execute the registration. Always include an Idempotency-Key header — if the request times out or returns 5xx, replay with the same key and the server deduplicates.

Charges to your account

POST /v3/domains/registrations charges the account's billing method. Verify the domain name and the quoted price before executing.

  • Submit the registration request:

    curl -s -X POST "https://api.godaddy.com/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-01-15T10:30:00.000Z",
          "agreementTypes": ["API_DPA"]
        }
      }'

Consent and idempotency requirements

Use the actual consent timestamp for agreedAt; synthetic values violate ICANN policy. Use the agreementTypes keys from requiredAgreements in the quote response; the registration returns INVALID_AGREEMENT_KEYS if they don't match. The period must match the quoted period, or you get QUOTE_MISMATCH. If you supplied a profile or profileId at quote time, re-supply the same value on execute or you get QUOTE_MISMATCH. The Idempotency-Key must be a unique UUID per attempt; retrying with the same key is safe after a timeout.

Poll the operation

The registration is asynchronous. Poll the returned registrationId URL every few seconds until the status reaches a terminal state.

  • Poll for the registration status:

    curl -s "https://api.godaddy.com/v3/domains/registrations/{registrationId}" \
      -H "Authorization: Bearer $GODADDY_PAT"
Rendering diagram...

Operation statuses

StatusMeaning
CONFIRMEDAccepted, processing in progress. Keep polling.
EXECUTINGActively executing. Keep polling.
COMPLETEDTerminal — succeeded. domain and expiresAt are populated.
FAILEDTerminal — failed.

You can also poll through GET /v3/domains/operations/{operationId}. Both endpoints resolve the same resource.

Use the CLI

After you set up the CLI (see the CLI reference for the full command list):

  1. Check availability:

    gddy domain available example.com
  2. Quote the domain:

    gddy domain quote example.com
  3. Register the domain:

    gddy domain purchase example.com --agree --confirm

    Registration is paid and not reversible. Run without --agree first to review the required agreements, and use --dry-run to preview before confirming.

    Use gddy domain contacts init to save default contacts for repeated purchases — the command writes a local contacts.toml template that the purchase command can use.

Registration body fields

The following table lists the fields required for the registration body.

FieldRequiredDescription
quoteTokenYesToken from POST /v3/domains/registration-quotes.
domainYesFully-qualified domain name to register.
periodYesRegistration period in years (must match the quoted period).
consentYesICANN consent object capturing the agreement type, consenting party, and timestamp listed in the Consent object fields table.
Idempotency-Key headerYesUUID generated per request.

The following table lists the fields required for the consent object.

FieldRequiredDescriptionNote
agreementTypesYesAgreement type keys from the TLD's required agreements (for example, API_DPA).Get these from the requiredAgreements field in the quote response.
agreedAtYesActual ISO 8601 timestamp of when the user consented.

Common errors

The following table lists common errors and recommended actions. Go to Errors for the full error envelope.

StatusMost likely causeRecommended action
400Malformed request body or missing required field.Inspect fields[] in the error response.
403Credential lacks write access, no payment method on file, or account billing issue.Check code to distinguish.
404TLD not supported.
409Domain is already registered (by anyone).
422 QUOTE_MISMATCHThe period or registration profile/profileId in the execute body doesn't match the quote.Re-use the same period, profile, and profileId from the quote, or fetch a new quote.
422 INVALID_AGREEMENT_KEYSWrong agreementTypes value.Use the keys returned in requiredAgreements from the quote response.
422 MISSING_CONTACTNo registrant contact on the account profile.Add a registrant contact to the account profile.
422 MISSING_BILLING_PHONEContact phone is missing or malformed.Verify phone.countryCode and phone.nationalNumber are both set.
422Domain isn't available, missing or invalid consent, or other contact validation failure.Inspect fields[] for specifics.

Additional information

Agent & Automation Notes

PermissionsDomain Registration
Scopesdomains.domain:read, domains.domain:create
Rate limitRate-limited per credential per window. Go to /docs/api-users/rate-limits for current values.
IdempotentNo
DestructiveNo
On failureRegistration charges the account and is not reversible. Use the Idempotency-Key header to prevent duplicate purchases. If the operation status is EXECUTING, poll — do not resubmit.

Last updated on

How is this guide?

On this page