A Python CLI for managing DNS at Name.com:
- Clone records from one domain to another
- Import from a CSV (Name.com export format)
- Manually add a single record from the command line
- Safe, correct upserts (no accidental duplicates)
- MX failsafe that checks deliverability before creating the record
-
Auth: HTTP Basic with
USERNAME:APITOKEN -
Clone:
--from old.com --to new.com -
CSV import: reads
Type,Host,Answer,TTL,Priority -
Map suffix:
--map-suffix old.com=new.com(find/replace on FQDN suffixes) -
Upsert: updates existing records instead of duplicating
- MX/SRV match on
(host, type, priority) - All matches use relative host normalized to the target zone
- MX/SRV match on
-
Apex handling: sends empty host
""to API for root records (avoids@.domainerrors) -
Manual add:
--add --type TYPE --host HOST --answer ANSWER [--ttl N] [--pri N]- MX auto-forced to
@and short answers likeemailexpand toemail.<zone> - MX failsafe prompts to create A/AAAA/CNAME if the target doesn’t resolve; CNAME must resolve (or you’ll be re-prompted)
- MX auto-forced to
-
Dry run:
--dry-runshows actions without changing DNS -
Skips SOA/NS in bulk flows
- Python 3.9+
pip install requests
-
Create an API token in your Name.com account.
If you have MFA enabled, you have to go and enable the API. The API does not use MFA and is off by default. -
Test auth:
curl -u USERNAME:APITOKEN https://api.name.com/core/v1/hello -
Clone one zone into another (upsert):
python main.py \ --token 'USERNAME:APITOKEN' \ --from old.com \ --to new.com \ --upsert
python main.py --token 'user:apitoken' --from old.com --to new.com --upsert
- Keeps the same labels (
www,api, etc.) in the new zone. - Use
--dry-runto preview.
python main.py --token 'user:apitoken' --csv dns.csv --to example.com --upsert
CSV format (header required):
Type,Host,Answer,TTL,Priority
A,www.example.com,203.0.113.10,300,
MX,example.com,mail.example.net.,300,10
TXT,@,"v=spf1 include:_spf.example.net ~all",300,
Notes:
Hostmay be FQDN or relative (@,www).Priorityapplies to MX (and SRV);TTLdefaults to 300 if blank.- CSV import supports SRV if present in API source; SRV extras (port/weight) aren’t in the CSV format here.
python main.py \
--token 'user:apitoken' \
--from old.com \
--csv extras.csv \
--to new.com \
--upsert
python main.py \
--token 'user:apitoken' \
--csv exported.csv \
--to new.com \
--map-suffix old.com=new.com \
--upsert
Use this if your CSV or source contains fully qualified names that still end with the old zone. It just finds and replaces the suffix.
# A/AAAA/TXT/CNAME, etc.
python main.py \
--token 'user:apitoken' \
--to example.com \
--add \
--type A \
--host www \
--answer 203.0.113.10 \
--ttl 300 \
--upsert
python main.py \
--token 'user:apitoken' \
--to example.com \
--add \
--type MX \
--answer email \
--pri 25 \
--ttl 300 \
--upsert
-
Host is forced to
@(apex) automatically. -
Short answers like
emailexpand toemail.example.com. -
The script resolves the MX target and:
-
If it resolves: proceeds.
-
If it doesn’t resolve: prompts to create A/AAAA/CNAME for that host.
- If you pick CNAME, its target must resolve (or you’re re-prompted).
- You’ll be asked for TTL (default 300) when creating the host record.
-
-
Apex records: Internally you’ll see
@, but the API payload uses empty host""to avoidInvalid Host: @.domain. -
Upsert matching:
- Normalizes both “existing” and “desired” to relative names for the target zone.
- MX/SRV match key:
(host, type, priority) - Others match key:
(host, type)
-
Suffix mapping:
--map-suffix old.zone=new.zonesimply replaces the trailing.old.zonewith.new.zoneon FQDNs before normalizing to the target zone.
Dry run preview:
python main.py --token 'user:apitoken' --from old.com --to new.com --upsert --dry-run
Add a root A record:
python main.py --token 'user:apitoken' --to example.com --add --type A --host @ --answer 198.51.100.7 --ttl 300 --upsert
Add a CNAME:
python main.py --token 'user:apitoken' --to example.com --add --type CNAME --host www --answer root.example.net. --ttl 600 --upsert
-
401 Unauthorized
- Confirm you’re using
USERNAME:APITOKEN(not your account password). - Test with:
curl -u user:token https://api.name.com/core/v1/hello
- Confirm you’re using
-
400 Invalid Host:
@.domain- Handled by the script (apex sent as
""to the API). If you edited the code, ensure the API payload converts@→"".
- Handled by the script (apex sent as
-
Unexpected duplicates on upsert
- Ensure you’re running the version that matches MX/SRV on
(host, type, priority). - Use
--dry-runto see exactly what the script plans to do.
- Ensure you’re running the version that matches MX/SRV on
-
MX failsafe loop
- If you choose CNAME and its target doesn’t resolve, creation is blocked to avoid mail disruption. Choose A/AAAA or provide a resolvable CNAME target.
- Always start with
--dry-runon production zones. - When cloning, run on a non-critical domain first to validate.
- After MX changes, verify the target host has A/AAAA (or a CNAME that ultimately resolves to A/AAAA).
MIT. No warranty; use at your own risk.