Skip to content
Start here

Registrar

Registrar API for searching, checking, registering, and managing domains through Cloudflare Registrar.

Prerequisites

Before using this API, ensure:

  1. Cloudflare account — the caller must have a valid Cloudflare account.
  2. Billing profile — the account must have a billing profile with a valid, current default payment method (credit card or other accepted method). This cannot be set up via API — the account owner must configure billing at https://dash.cloudflare.com/{account_id}/billing/payment-info before calling POST /registrations.
  3. API authentication — use an API token or API key with the appropriate Registrar permissions for the operations you are calling.

Terminology: domain extension

Throughout this API, “extension” refers to the domain extension part of a fully qualified domain name — the portion after the registrable label. For example, in example.co.uk, the extension is co.uk (not just uk). This covers both top-level domains like com and multi-level extensions like co.uk. This is distinct from other uses of the word “extension” (e.g., EPP extensions).

Supported extensions

This API supports programmatic registration for all extensions supported by the dashboard experience, with the following exceptions:

giving, mom, inc, lol, sh, link, cc, new

Cloudflare Registrar supports 400+ extensions in the dashboard. Extensions listed above can be registered at https://dash.cloudflare.com/{account_id}/domains/registrations.

Typical workflow

  1. Search — call GET /domain-search?q={keyword} to discover available domains.
  2. Check — call POST /domain-check with candidate domains to verify real-time availability and pricing.
  3. Review the response — if registrable: false, inspect reason to understand whether the domain is unavailable, the extension is not supported by this API, the extension is not supported by Cloudflare Registrar at all, or the extension’s registry has frozen new registrations.
  4. Handle premium domains — if tier: premium, premium registration is not currently supported by this API. Surface the premium pricing to the user, but do not proceed to POST /registrations for that domain.
  5. Observe the registration schema — call GET /extensions/:extension_name to discover the required values for registering this extension.
  6. Register — call POST /registrations with the chosen domain name for supported non-premium registrations.
  7. Confirm completion — if the response is 201 Created, registration completed within the default timeout and no polling is needed.
  8. Poll when needed — if the response is 202 Accepted, poll links.self from the workflow response.
  9. Stop for user action — if state: action_required, stop polling and surface context.action to the user. The workflow will not resolve on its own.
  10. Continue when blocked — if state: blocked, continue polling and inform the user that a third party, such as the extension registry or losing registrar, is delaying progress.
  11. Review failures before retrying — if state: failed, review error.code and error.message, then decide whether user action or a new Check call is needed.

All successful domain registrations are non-refundable. Once the registration workflow completes with state: succeeded, the charge cannot be reversed. Confirm pricing and domain choice with the user before calling POST /registrations.

Default behavior for mutating operations

By default, mutating operations such as create and update hold the connection for a bounded, server-defined amount of time while the operation completes. In most cases, the response contains a completed workflow status and no polling is required.

  • Completed within the synchronous wait window: Returns 201 (create) or 200 (update) with a workflow_status where state: succeeded and completed: true.
  • Still processing after the synchronous wait window: Returns 202 Accepted with a workflow_status where completed: false. Use the links.self URL to poll for completion.

Non-blocking mode

To receive an immediate 202 Accepted response without waiting, send the Prefer: respond-async request header (RFC 7240). The server will acknowledge it with a Preference-Applied: respond-async response header.

Polling

When the response is 202, poll the workflow status endpoint indicated by links.self in the response body until the workflow reaches a terminal state or requires user action.

Search for available domains
client.Registrar.Search(ctx, params) (*RegistrarSearchResponse, error)
GET/accounts/{account_id}/registrar/domain-search
Check domain availability
client.Registrar.Check(ctx, params) (*RegistrarCheckResponse, error)
POST/accounts/{account_id}/registrar/domain-check
ModelsExpand Collapse
type Registration struct{…}

A domain registration resource representing the current state of a registered domain.

AutoRenew bool

Whether automatic renewal occurs before expiration.

CreatedAt Time

When the domain was registered. Present when the registration resource exists.

formatdate-time
DomainName string

Provides a fully qualified domain name (FQDN), including the extension (e.g., example.com, mybrand.app). The domain name uniquely identifies a registration. Cloudflare permits only one registration per domain, making the domain name a natural idempotency key for registration requests.

ExpiresAt Time

When the domain registration expires. Ready registrations include this value; only registration_pending may return null.

formatdate-time
Locked bool

Whether the domain is locked for transfer.

PrivacyMode RegistrationPrivacyMode

Current WHOIS privacy mode for the registration.

One of the following:
const RegistrationPrivacyModeOff RegistrationPrivacyMode = "off"
const RegistrationPrivacyModeRedaction RegistrationPrivacyMode = "redaction"
Status RegistrationStatus

Current registration status.

  • active: The domain operates with an active registration.
  • registration_pending: Registration remains in progress.
  • expired: The domain registration expired.
  • suspended: The registry suspended the domain.
  • redemption_period: The domain entered the redemption grace period.
  • pending_delete: The registry scheduled the domain for deletion.
One of the following:
const RegistrationStatusActive RegistrationStatus = "active"
const RegistrationStatusRegistrationPending RegistrationStatus = "registration_pending"
const RegistrationStatusExpired RegistrationStatus = "expired"
const RegistrationStatusSuspended RegistrationStatus = "suspended"
const RegistrationStatusRedemptionPeriod RegistrationStatus = "redemption_period"
const RegistrationStatusPendingDelete RegistrationStatus = "pending_delete"
type WorkflowStatus struct{…}

Status of an async registration workflow.

Completed bool

Indicates whether the workflow reached a terminal state. A succeeded or failed state returns true; pending, in_progress, action_required, and blocked return false.

CreatedAt Time
formatdate-time
State WorkflowStatusState

Describes the workflow lifecycle state.

  • pending: The workflow awaits processing.
  • in_progress: Processing started. Continue polling links.self. An internal deadline limits the duration of this state.
  • action_required: The workflow pauses for user action. See context.action for details. Stop automated polling until the user completes the required action.
  • blocked: A third party, such as the domain extension’s registry or a losing registrar, prevents progress. Continue polling because the block may resolve when the third party responds.
  • succeeded: Terminal state. The operation completed successfully. completed equals true. For registrations, context.registration contains the resulting registration resource.
  • failed: Terminal state. The operation failed. completed equals true. See error.code and error.message for the reason. Require user review before retrying.
One of the following:
const WorkflowStatusStatePending WorkflowStatusState = "pending"
const WorkflowStatusStateInProgress WorkflowStatusState = "in_progress"
const WorkflowStatusStateActionRequired WorkflowStatusState = "action_required"
const WorkflowStatusStateBlocked WorkflowStatusState = "blocked"
const WorkflowStatusStateSucceeded WorkflowStatusState = "succeeded"
const WorkflowStatusStateFailed WorkflowStatusState = "failed"
UpdatedAt Time
formatdate-time
Context map[string, unknown]Optional

Provides workflow-specific data.

For domain-centric workflows, context.domain_name identifies the workflow subject.

Error WorkflowStatusErrorOptional

Provides error details when a workflow reaches the failed state. The workflow type (registration, update, etc.) and underlying registry response determine the specific codes and messages. Workflow error codes differ from immediate HTTP error errors[].code values in non-2xx responses. Surface error.message to the user for context.

Code string

Machine-readable error code identifying the failure reason.

Message string

Human-readable explanation of the failure. May include registry-specific details.

RegistrarDomains

List domains
Deprecated
client.Registrar.Domains.List(ctx, query) (*SinglePage[Domain], error)
GET/accounts/{account_id}/registrar/domains
Get domain
Deprecated
client.Registrar.Domains.Get(ctx, domainName, query) (*DomainGetResponse, error)
GET/accounts/{account_id}/registrar/domains/{domain_name}
Update domain
Deprecated
client.Registrar.Domains.Update(ctx, domainName, params) (*DomainUpdateResponse, error)
PUT/accounts/{account_id}/registrar/domains/{domain_name}
ModelsExpand Collapse
type Domain struct{…}
ID stringOptional

Domain identifier.

maxLength32
Available boolOptional

Shows if a domain is available for transferring into Cloudflare Registrar.

CanRegister boolOptional

Indicates eligibility to register the domain as a new domain.

CreatedAt TimeOptional

Shows time of creation.

formatdate-time
CurrentRegistrar stringOptional

Shows name of current registrar.

ExpiresAt TimeOptional

Shows when domain name registration expires.

formatdate-time
Locked boolOptional

Shows whether a registrar lock is in place for a domain.

RegistrantContact DomainRegistrantContactOptional

Shows contact information for domain registrant.

Address string

Address.

City string

City.

Country string

The country in which the user lives.

maxLength30
FirstName string

User’s first name.

maxLength60
LastName string

User’s last name.

maxLength60
Organization string

Name of organization.

Phone string

User’s telephone number.

maxLength20
State string

State.

Zip string

The zipcode or postal code where the user lives.

maxLength20
ID stringOptional

Contact Identifier.

maxLength32
Address2 stringOptional

Optional address line for unit, floor, suite, etc.

Email stringOptional

The contact email address of the user.

maxLength90
Fax stringOptional

Contact fax number.

RegistryStatuses stringOptional

A comma-separated list of registry status codes. Refer to EPP Status Codes for the full list.

SupportedTLD boolOptional

Indicates whether Cloudflare Registrar currently supports a particular TLD. Refer to TLD Policies for a list of supported TLDs.

TransferIn DomainTransferInOptional

Statuses for domain transfers into Cloudflare Registrar.

AcceptFoa DomainTransferInAcceptFoaOptional

Status of the registrant authorization step.

One of the following:
const DomainTransferInAcceptFoaNeeded DomainTransferInAcceptFoa = "needed"
const DomainTransferInAcceptFoaOk DomainTransferInAcceptFoa = "ok"
ApproveTransfer DomainTransferInApproveTransferOptional

Status of the registry transfer-approval step.

One of the following:
const DomainTransferInApproveTransferNeeded DomainTransferInApproveTransfer = "needed"
const DomainTransferInApproveTransferOk DomainTransferInApproveTransfer = "ok"
const DomainTransferInApproveTransferPending DomainTransferInApproveTransfer = "pending"
const DomainTransferInApproveTransferTrying DomainTransferInApproveTransfer = "trying"
const DomainTransferInApproveTransferRejected DomainTransferInApproveTransfer = "rejected"
const DomainTransferInApproveTransferUnknown DomainTransferInApproveTransfer = "unknown"
CanCancelTransfer boolOptional

Indicates if cancellation is still possible.

DisablePrivacy DomainTransferInDisablePrivacyOptional

Status of the privacy-guard disabling step at the foreign registrar.

One of the following:
const DomainTransferInDisablePrivacyNeeded DomainTransferInDisablePrivacy = "needed"
const DomainTransferInDisablePrivacyOk DomainTransferInDisablePrivacy = "ok"
const DomainTransferInDisablePrivacyUnknown DomainTransferInDisablePrivacy = "unknown"
EnterAuthCode DomainTransferInEnterAuthCodeOptional

Status of the auth-code entry and verification step.

One of the following:
const DomainTransferInEnterAuthCodeNeeded DomainTransferInEnterAuthCode = "needed"
const DomainTransferInEnterAuthCodeOk DomainTransferInEnterAuthCode = "ok"
const DomainTransferInEnterAuthCodePending DomainTransferInEnterAuthCode = "pending"
const DomainTransferInEnterAuthCodeTrying DomainTransferInEnterAuthCode = "trying"
const DomainTransferInEnterAuthCodeRejected DomainTransferInEnterAuthCode = "rejected"
UnlockDomain DomainTransferInUnlockDomainOptional

Status of the domain-unlock step at the foreign registrar.

One of the following:
const DomainTransferInUnlockDomainNeeded DomainTransferInUnlockDomain = "needed"
const DomainTransferInUnlockDomainOk DomainTransferInUnlockDomain = "ok"
const DomainTransferInUnlockDomainPending DomainTransferInUnlockDomain = "pending"
const DomainTransferInUnlockDomainTrying DomainTransferInUnlockDomain = "trying"
const DomainTransferInUnlockDomainUnknown DomainTransferInUnlockDomain = "unknown"
UpdatedAt TimeOptional

Last updated.

formatdate-time

RegistrarRegistrations

Create Registration
client.Registrar.Registrations.New(ctx, params) (*WorkflowStatus, error)
POST/accounts/{account_id}/registrar/registrations
List Registrations
client.Registrar.Registrations.List(ctx, params) (*CursorPagination[Registration], error)
GET/accounts/{account_id}/registrar/registrations
Get Registration
client.Registrar.Registrations.Get(ctx, domainName, query) (*Registration, error)
GET/accounts/{account_id}/registrar/registrations/{domain_name}
Update Registration
client.Registrar.Registrations.Edit(ctx, domainName, params) (*WorkflowStatus, error)
PATCH/accounts/{account_id}/registrar/registrations/{domain_name}

RegistrarRegistration Status

Get Registration Status
client.Registrar.RegistrationStatus.Get(ctx, domainName, query) (*WorkflowStatus, error)
GET/accounts/{account_id}/registrar/registrations/{domain_name}/registration-status

RegistrarUpdate Status

Get Update Status
client.Registrar.UpdateStatus.Get(ctx, domainName, query) (*WorkflowStatus, error)
GET/accounts/{account_id}/registrar/registrations/{domain_name}/update-status

RegistrarExtensions

List extensions
client.Registrar.Extensions.List(ctx, params) (*CursorPagination[ExtensionListResponse], error)
GET/accounts/{account_id}/registrar/extensions
Get extension
client.Registrar.Extensions.Get(ctx, extension, query) (*ExtensionGetResponse, error)
GET/accounts/{account_id}/registrar/extensions/{extension}