By Greg Nowak. Updated September 16, 2026.
A DNS change can be only one line long and still redirect a website, interrupt email, or expose an origin unexpectedly. That is why the Cloudflare API is useful during launches and migrations: not because every DNS edit needs automation, but because important changes should be inspectable, repeatable, and easy to hand over.
For most businesses and agencies, the right solution is not a large infrastructure project. A small, versioned script with a preflight check, explicit approval point, and post-change verification is often enough.
Choose the lightest workflow that controls the risk
The dashboard remains sensible for an isolated edit. Automation becomes valuable when several records must move together, the work will be repeated, or another person needs to review exactly what will happen.
| Situation | Recommended method | Essential control |
|---|---|---|
| One low-risk correction | Cloudflare dashboard | Second-person check for consequential records |
| Website launch or migration | Read, review, then write through the API | Confirm name, type, value, TTL, and proxy status |
| Repeatable client setup | Versioned script plus documented inputs | Separate configuration from credentials |
| Bulk zone migration | Export, clean, review, then import | Retain a dated pre-change export |
| CI preflight check | Read-only API request | No write permission in the checking job |
Give the token only the access the job needs
Use a scoped API token rather than a Global API key. Inventory and preflight jobs normally need DNS Read; a job that creates, updates, deletes, or imports records needs DNS Write. Restrict the token to the relevant zone. Where practical, also apply an expiry and a client-IP restriction.
A user token is appropriate for a named operator doing temporary or ad hoc work. For durable CI/CD integrations, Cloudflare now supports account-owned tokens for DNS. These act as service principals rather than depending on an employee account, although creating or updating one requires Super Administrator permission. Store either token in a secret manager, never in the repository or a copied command transcript.
The zone ID is configuration, not a secret. Supplying it directly also avoids granting Zone Read merely so a script can discover the zone.
: "${CLOUDFLARE_API_TOKEN:?set this through 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'Read the exact record before changing anything
A safe script does not begin with a write request. It first queries the fully qualified name and record type using the API’s exact-name filter. Avoid the general search parameter in automation because Cloudflare explicitly reserves that for human-oriented searching and does not guarantee its precise behavior.
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"Treat the result count as a decision point. Zero matches may justify a reviewed create request. One match may justify updating that record ID. Multiple matches can be legitimate—for example, several A records used for simple load distribution—so the script should stop instead of silently selecting the first result.
Before approval, show the current and proposed content, TTL, and proxy status. Cloudflare uses ttl: 1 for automatic TTL; otherwise the documented range is 60 to 86,400 seconds, with a 30-second minimum on Enterprise zones.
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":3600,"proxied":true,"comment":"App origin - OPS-142"}'PATCH is useful here because unspecified fields remain unchanged. Still, review record-type constraints before writing: a CNAME cannot share its name with A or AAAA records, and delegated names involving NS records need particular care.
Leave enough context for the next operator
A DNS comment does not affect resolution, but it can prevent detective work later. Use it for a concise owner, ticket number, migration reference, or planned removal date. Keep the full decision history in the project or ticketing system; the record comment should point to that history rather than replace it.
Also record who approved the production change, who ran it, and what should trigger rollback. That small audit trail is often more valuable than making the script technically elaborate.
Export before bulk changes or imports
For a migration, export the current zone before touching it and attach that file to the approved change. Review mail, verification, delegation, and service records as well as the obvious 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-change.txt
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]"Cloudflare currently limits imported zone files to 256 KiB and import/export API traffic to three requests per minute per user. Targets for CNAME, DNAME, MX, NS, PTR, and SRV records should be fully qualified and end with a period. Cloudflare supports $ORIGIN, $TTL, and $GENERATE, but rejects $INCLUDE. Its reserved cf-proxied:true and cf-proxied:false tags can preserve intentional proxy states.
Finish with external verification, not an API success message
Cloudflare’s batch endpoint can execute deletes, patches, puts, and posts in one database transaction, and a failed individual action prevents the batch from being applied. Propagation across Cloudflare’s distributed network is not atomic, however. A successful response does not mean every observer sees every new record simultaneously.
- Confirm the intended records through the API after writing.
- Query public DNS from outside the Cloudflare account.
- Test the actual website, certificate, mail route, or verification flow affected.
- Retain the pre-change export and record the final outcome.
- Remove or rotate temporary write tokens after the migration.
If DNS remains a fragile step in launches or agency handovers, Greg can help turn these commands into a reviewed operating process your team can safely run and maintain.
Related on GrN.dk
- AI automations need a spend dashboard before the first runaway bill
- Your AI workflow has logs. Can they explain one bad decision?
- Cloudflare Service Keys Stop in September: Find Every Caller
Need help with this kind of work?
Plan a safer DNS workflow with Greg Get in touch with Greg.