Cloudflare API: Safer DNS Automation for Launches and Migrations

Illustrated infographic summarizing: Cloudflare API: Safer DNS Automation for Launches and Migrations

By Greg Nowak. Updated October 16, 2026.

A website migration is nearly finished, the new hosting works, and someone says: “We just need to change DNS.” That last step deserves its own plan. A small edit can send visitors to the wrong server, interrupt email, or change whether traffic passes through Cloudflare.

The Cloudflare API helps make those changes reviewable and repeatable. For a business owner or agency lead, the useful outcome is straightforward: someone owns the change, another person can understand it, and the team knows how to recover.

Choose a workflow your team can maintain

A dashboard edit is reasonable for an isolated correction. Automation earns its place when a launch involves several records, client setups repeat, or a reviewer needs to approve an exact change.

Situation Practical approach Before proceeding
Single correction Dashboard edit Check the existing value and affected service
Website migration API read, review, then update Agree the new origin, proxy status, and rollback
Repeated agency setup Versioned script with separate configuration Confirm the client zone and credential scope
Bulk record changes Reviewed import or batch request Export first and identify conflicting records
Automated preflight Read-only API job Keep production write access out of the job
Choose automation where it makes DNS changes easier to review, repeat, or recover.

Limit access and settle ownership first

Use a scoped API token instead of a Global API key. Give inventory jobs DNS Read and change jobs DNS Write, restricted to the relevant zone. Keep credentials in a secret store and out of repositories, screenshots, and shell tracing.

User tokens suit temporary operator tasks. For ongoing integrations, Cloudflare supports account API tokens for DNS, so automation need not depend on an employee’s account. Creating them requires API Token Provisioning capabilities or Super Administrator status; permissions granted must remain within the creator’s own access.

Before launch, name the approver, operator, and person responsible for checking the service. Supply the zone ID directly as configuration.

: "${CLOUDFLARE_API_TOKEN:?load from your secret store}"
: "${ZONE_ID:?set the target zone ID}"
: "${DNS_NAME:?set the fully qualified record name}"
CF_API='https://api.cloudflare.com/client/v4'

Export first, then write down the reverse change

Save a dated export before a migration. Review email, verification, and delegation records alongside the website records.

curl --fail-with-body --silent --show-error \
  "$CF_API/zones/$ZONE_ID/dns_records/export" \
  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
  --output "zone-before-$(date -u +%Y%m%dT%H%M%SZ).txt"

An export is useful recovery material, but a rollback needs explicit reverse changes: which values to restore, which newly created records to remove, and who can authorise that action. Keep the previous hosting available through the agreed verification period.

For bulk imports, Cloudflare documents a 256 KiB file limit and three import requests per minute per user. Domain-name targets such as MX and CNAME content should end with a period. Preserve intentional cf-proxied:true or cf-proxied:false tags. Supported directives include $ORIGIN, $TTL, and $GENERATE; $INCLUDE is unsupported.

curl --fail-with-body --silent --show-error \
  "$CF_API/zones/$ZONE_ID/dns_records/import" \
  --request POST \
  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
  --form "[email protected]"

Read the exact record and stop on surprises

Query the fully qualified name and record type before writing. Cloudflare’s record-list API provides exact filters; its general search parameter is intended for people and has deliberately unspecified matching behaviour.

curl --fail-with-body --silent --show-error --get \
  "$CF_API/zones/$ZONE_ID/dns_records" \
  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
  --data-urlencode "type=A" \
  --data-urlencode "name.exact=$DNS_NAME" \
  --data-urlencode "match=all"

Check success, errors, and result_info.total_count, rather than counting only the returned page. Zero matches calls for investigation before creating anything, including checking other record types. One match gives you a candidate record ID. Multiple matches may be intentional; stop for review instead of selecting the first.

Show the current and proposed name, type, content, TTL, and proxy status for approval. Immediately before writing, read again and stop if the approved starting state has changed.

Update only the approved fields

The following PATCH request illustrates an approved A-record update. The IP address is a documentation placeholder: replace it with the reviewed origin address. Set DNS_RECORD_ID from the inspected response.

: "${DNS_RECORD_ID:?set the reviewed record ID}"
curl --fail-with-body --silent --show-error \
  "$CF_API/zones/$ZONE_ID/dns_records/$DNS_RECORD_ID" \
  --request PATCH \
  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
  --header "Content-Type: application/json" \
  --data '{"content":"198.51.100.4","ttl":1,"proxied":true,"comment":"Website origin migration"}'

Here, ttl: 1 means automatic TTL. The request also explicitly enables proxying; keep that field aligned with the approved plan. PATCH leaves unspecified fields unchanged. Check type constraints when restructuring records: A/AAAA records cannot coexist with a CNAME at the same name.

On repeat runs, skip records already in the desired state. If a write times out, read the record again before retrying.

Verify the service before closing the launch

Cloudflare’s batch endpoint applies operations in one database transaction and rejects the batch if an individual action fails. Distribution across its network is not atomic, so API success alone does not establish that every observer sees the change.

  1. Read back the changed records through the API.
  2. Query public DNS, checking both A and AAAA where relevant.
  3. Test the actual website, certificate, email route, or verification flow.
  4. Record the outcome and revoke temporary write tokens.
dig @1.1.1.1 "$DNS_NAME" A +short
dig @1.1.1.1 "$DNS_NAME" AAAA +short

For proxied records, public answers identify Cloudflare’s edge rather than proving which origin served the request. Check the application response or origin logs too.

If DNS changes keep becoming an uncertain last step, Greg can help plan the migration and document the operating process, giving your team clear responsibilities, verification steps, and a usable handover.

Related on GrN.dk

Need help with this kind of work?

Plan a safer DNS migration with Greg Get in touch with Greg.

Sources

Latest articles

Check how your chatbot identifies itself as AI, where requests for human help actually go, and what customers encounter when support is unavailable.

Start with one website change on board.nowa.dk. Write a clear task, answer questions as they arise and review the result before giving an AI agent more work.

Keep AI search visibility, training preferences and assistant access separate. Use a practical policy matrix to check Cloudflare settings and test key public pages.

Let AI draft Black Friday campaigns using approved product data. Check prices and recipients, and secure approval before sending the campaign from Mailchimp.

Make AI meeting notes useful after the call: confirm decisions, agree owners and deadlines, check existing tasks, and verify that work reaches the right tracker.

Before tuning your AI chatbot, check whether your PDFs supply readable text, reliable reading order, usable tables, and passages you can trace to the page.

Bring quote request emails from Outlook into your CRM with AI. Define fields, duplicate checks and sales ownership, then use a pilot to measure whether the solution saves time and helps more enquiries get followed up.

Plan your PHP upgrade around checkout, enquiries and daily operations, with practical checks for compatibility, staging, deployment and rollback before support ends.

Claude Sonnet 4.5 has a tentative November 30 retirement date. Find affected workflows, check compatibility and test a supported replacement before switching.

Before closing an Apache patch ticket, check what is running, which fixes the package contains, and whether the updated service passes configuration and application checks.