Skip to content

Registrar API

Use the Cloudflare Registrar API to search for domain names, check real-time availability and pricing, and register supported domains programmatically.

This guide walks through the beta workflow using the Cloudflare API and curl. These same endpoints are in the official Cloudflare API reference and through Cloudflare MCP by default, which means they can be used from scripts, backend services, CI pipelines, and agent-driven tools without additional integration work.

Before you begin

Before you make your first API request, make sure you have:

  1. A Cloudflare account ID.
  2. An API token with Registrar write permissions. Create one at https://dash.cloudflare.com/<ACCOUNT_ID>/api-tokens.
  3. A billing profile with a valid default payment method. Manage billing at https://dash.cloudflare.com/<ACCOUNT_ID>/billing/payment-info.
  4. A default registrant contact configured on the account, plus acceptance of the Domain Registration Agreement on the registrations page: https://dash.cloudflare.com/<ACCOUNT_ID>/domains/registrations.

For related setup help, refer to:

Set up authentication

Cloudflare API requests use bearer token authentication.

In your terminal, define environment variables for your account ID and API token:

Terminal window
export ACCOUNT_ID="<YOUR_ACCOUNT_ID>"
export CLOUDFLARE_API_TOKEN="<YOUR_API_TOKEN>"

All requests in this guide use the Cloudflare API v4 base URL:

https://api.cloudflare.com/client/v4/

Beta workflow

The beta workflow has three core steps:

  1. Search for candidate domain names.
  2. Check real-time availability and pricing for the domain you want.
  3. Register the domain.

Search is useful for discovery, but it is not the source of truth. Always call the Check endpoint immediately before registration to reduce the likelihood of hitting an error during registration.

Example prompts for agents

If you are using Cloudflare MCP or another agent-driven workflow, prompts can be as simple as:

  • Search for domains for a coffee shop based in Evergreen, Colorado.
  • Find 5 available .com or .dev domains for an AI expense tracker.
  • Check whether evergreenbean.com is available and show me the current price.
  • Check these domains and tell me which ones are registrable right now: evergreenbean.com, evergreenbean.dev, evergreen.cafe
  • Register evergreenbean.com on my Cloudflare account.

1. Search for domains

Use the Search endpoint to generate candidate domain names from a keyword, phrase, or partial domain name.

Search results:

  • Are fast and intended for discovery.
  • Are based on cached data.
  • Only include extensions supported by the API beta.
Terminal window
curl --request GET \
--url "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/registrar/domain-search?q=acme%20corp&limit=3" \
--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN"

Example response:

{
"success": true,
"errors": [],
"messages": [],
"result": {
"domains": [
{
"name": "acmecorp.com",
"registrable": true,
"tier": "standard",
"pricing": {
"currency": "USD",
"registration_cost": "8.57",
"renewal_cost": "8.57"
}
},
{
"name": "acmecorp.dev",
"registrable": true,
"tier": "standard",
"pricing": {
"currency": "USD",
"registration_cost": "10.11",
"renewal_cost": "10.11"
}
},
{
"name": "acmecorp.app",
"registrable": true,
"tier": "standard",
"pricing": {
"currency": "USD",
"registration_cost": "11.00",
"renewal_cost": "11.00"
}
}
]
}
}

2. Check real-time availability and pricing

Use the Check endpoint to confirm whether a domain is currently registrable and to retrieve the current price.

Check results:

  • Query the registry directly.
  • Reflect current registry state.
  • Should be used immediately before calling the registration endpoint.
  • Responses can include a reason field when registrable is false.

This endpoint accepts up to 20 domains per request.

Terminal window
curl --request POST \
--url "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/registrar/domain-check" \
--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"domains": ["acmecorp.dev"]
}'

Example response:

{
"success": true,
"errors": [],
"messages": [],
"result": {
"domains": [
{
"name": "acmecorp.dev",
"registrable": true,
"tier": "standard",
"pricing": {
"currency": "USD",
"registration_cost": "10.11",
"renewal_cost": "10.11"
}
}
]
}
}

If a domain cannot be registered through the API, the response includes a reason. For example:

{
"success": true,
"errors": [],
"messages": [],
"result": {
"domains": [
{
"name": "mybrand.uk",
"registrable": false,
"reason": "extension_not_supported_via_api"
}
]
}
}

Common reason values include:

  • domain_unavailable
  • extension_not_supported_via_api
  • extension_not_supported
  • extension_disallows_registration

3. Register a domain

Use the Registration endpoint to start a domain registration workflow.

Important:

  • Successful registrations are billable to the default payment profile.
  • Registrations are non-refundable once they complete successfully.
  • Always confirm the domain name and price before calling this endpoint.

The simplest request only requires domain_name:

Terminal window
curl --request POST \
--url "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/registrar/registrations" \
--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"domain_name": "acmecorp.dev"
}'

The account must have a default registrant contact configured. If you do not pass a new contact inline, the API uses the default contact automatically. If you want to register the domain with a different contact, you can pass that contact in the request.

Current default behavior:

  • auto_renew defaults to false.
  • privacy_mode defaults to redaction when supported for the TLD, otherwise off.
  • The account's default payment method is charged automatically.

To override the default registrant contact for a single registration, provide one inline:

Terminal window
curl --request POST \
--url "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/registrar/registrations" \
--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"domain_name": "acmecorp.dev",
"contacts": {
"registrant": {
"email": "ada@example.com",
"phone": "+1.5555555555",
"postal_info": {
"name": "Ada Lovelace",
"organization": "Example Inc",
"address": {
"street": "123 Main St",
"city": "Austin",
"state": "TX",
"postal_code": "78701",
"country_code": "US"
}
}
}
}
}'

Example successful response:

{
"success": true,
"errors": [],
"messages": [],
"result": {
"domain_name": "acmecorp.dev",
"state": "succeeded",
"completed": true,
"created_at": "2025-10-27T10:00:00Z",
"updated_at": "2025-10-27T10:00:03Z",
"context": {
"registration": {
"domain_name": "acmecorp.dev",
"status": "active",
"created_at": "2025-10-27T10:00:00Z",
"expires_at": "2026-10-27T10:00:00Z",
"auto_renew": false,
"privacy_mode": "redaction",
"locked": true
}
},
"links": {
"self": "/accounts/abc/registrar/registrations/acmecorp.dev/registration-status",
"resource": "/accounts/abc/registrar/registrations/acmecorp.dev"
}
}
}

Handle registration responses

By default, the registration endpoint waits for up to 10 seconds before responding.

You can receive either:

  • 201 Created if the registration completed within the wait window.
  • 202 Accepted if the registration is still in progress.

To force immediate asynchronous behavior, send Prefer: respond-async.

Example asynchronous request:

Terminal window
curl --request POST \
--url "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/registrar/registrations" \
--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
--header "Content-Type: application/json" \
--header "Prefer: respond-async" \
--data '{
"domain_name": "acmecorp.dev"
}'

Example 202 Accepted response:

{
"success": true,
"errors": [],
"messages": [],
"result": {
"domain_name": "acmecorp.dev",
"state": "in_progress",
"completed": false,
"created_at": "2025-10-27T10:00:00Z",
"updated_at": "2025-10-27T10:00:10Z",
"links": {
"self": "/accounts/abc/registrar/registrations/acmecorp.dev/registration-status",
"resource": "/accounts/abc/registrar/registrations/acmecorp.dev"
}
}
}

Poll registration status

If the registration is still in progress, poll the status endpoint until the workflow reaches a terminal state.

Terminal window
curl --request GET \
--url "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/registrar/registrations/acmecorp.dev/registration-status" \
--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN"

Example response:

{
"success": true,
"errors": [],
"messages": [],
"result": {
"domain_name": "acmecorp.dev",
"state": "succeeded",
"completed": true,
"created_at": "2025-10-27T10:00:00Z",
"updated_at": "2025-10-27T10:00:03Z",
"context": {
"registration": {
"domain_name": "acmecorp.dev",
"status": "active",
"created_at": "2025-10-27T10:00:00Z",
"expires_at": "2026-10-27T10:00:00Z",
"auto_renew": false,
"privacy_mode": "redaction",
"locked": true
}
},
"links": {
"self": "/accounts/abc/registrar/registrations/acmecorp.dev/registration-status",
"resource": "/accounts/abc/registrar/registrations/acmecorp.dev"
}
}
}

Possible workflow states include:

  • in_progress
  • succeeded
  • failed
  • action_required
  • blocked

If the workflow returns action_required, stop polling and surface the required user action.

If the workflow returns failed, inspect error.code and error.message before retrying.

Get the registration resource

Once registration is complete, retrieve the registration resource directly:

Terminal window
curl --request GET \
--url "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/registrar/registrations/acmecorp.dev" \
--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN"

Example response:

{
"success": true,
"errors": [],
"messages": [],
"result": {
"domain_name": "acmecorp.dev",
"status": "active",
"created_at": "2025-10-27T10:00:00Z",
"expires_at": "2026-10-27T10:00:00Z",
"auto_renew": false,
"privacy_mode": "redaction",
"locked": true
}
}

Beta limitations

This is the first beta release of the Registrar API.

Current limitations include:

  • Only a subset of supported Cloudflare Registrar extensions are available through the API beta.
  • Search results are scoped to API-supported extensions only.
  • Some extensions supported in the dashboard are not yet available for programmatic registration.
  • Premium domains require explicit fee acknowledgement before registration.
  • Renewals are not yet available through the API.
  • Transfers are not yet available through the API.
  • Contact updates are not yet available through the API.

If you check a domain that Cloudflare supports in the dashboard but not yet in the API, the Check response returns extension_not_supported_via_api.

These core Registrar functions will be added in future versions of the API.

Add a link here to the supported extensions list once it exists.

Next steps

If you are building with the Registrar API beta, especially for automation, agents, or multi-tenant platform workflows, we want your feedback.