Automating Bulk Domain Registration with Route 53
Registering domains one by one through the AWS Console is tedious — especially when you're managing multiple clients across different AWS accounts. To solve this, I built a Bash script that automates the entire process: checking availability, validating pricing, and registering domains in bulk via the Route 53 Domains API.
What the script does
The Route 53 Express Domain Buyer iterates through a list of desired domain name variants, checks their availability, validates the registration price against a configurable cap, and optionally registers the first affordable available variant for each entry — all from the command line.
How to use it
bash./express-buyer.sh # Dry-run — checks and logs, no purchases ./express-buyer.sh --execute # Live run — registers domains for real
Always run a dry-run first to verify what the script intends to register before committing to any purchases.
Configuration
Before running the script, edit the following variables at the top of the file:
- MAX_PRICE — maximum registration price in USD (default 15)
- PAUSE — seconds to sleep between API calls, to avoid throttling (default 1)
- CONTACT_JSON — registrant contact details sent to Route 53
- DOMAINS — pipe-delimited rows of domain name variants to try
Contact details — update this block with the real registrant information:
jsonCONTACT_JSON='{ "FirstName": "Michael", "LastName": "Jackson", "ContactType": "COMPANY", "OrganizationName": "Amazon Web Services", "AddressLine1": "123 Cloud St", "City": "Seattle", "CountryCode": "US", "ZipCode": "98101", "PhoneNumber": "+1.2065551234", "Email": "michael.jackson@amazon.com" }'
Domain list — each row follows the format "row|name1|name2|name3". The script tries each name variant with .com first, then .org, and stops as soon as it finds one that is available and within the price cap:
bashdeclare -a DOMAINS=( "1|google|googlehub|googleng" "2|facebook|facebookhub|facebookng" "3|amazon|amazonhub|amazonng" )
What happens at runtime
For each row in the domains list, the script:
- Checks domain availability via route53domains:CheckDomainAvailability
- Looks up the registration price via route53domains:ListPrices
- Skips any domain priced above MAX_PRICE
- In dry-run mode, logs what it would register
- In execute mode, calls route53domains:RegisterDomain with privacy protection enabled on all three contact types (admin, registrant, tech)
Duplicate domain entries are detected and skipped automatically.
Output files
- domain-bought.txt — full timestamped log and structured result lines for every domain processed
- domain-errors.txt — errors only: API failures, unsupported TLDs, registration failures
Result lines in domain-bought.txt follow a structured format, making them easy to parse or pipe into other tools:
textREGISTERED|1|google.com|$12.00|op-xxxxxxxx DRY_RUN|2|facebookhub.org|$9.99|- ERROR|3|amazon|all_variants_failed|-
Sample output
text================================================ Route53 Domain Registration Mode : DRY-RUN Max : $15 Started : 2025-01-15 10:32:01 ================================================ [Row 1] Trying: google / googlehub / googleng [.com] unavailable (registered) [.org] unavailable (registered) [.com] unavailable (registered) [.org] AVAILABLE @ $9.99 ✓ >>> [DRY-RUN] Would register: googlehub.org @ $9.99 [Row 2] Trying: facebook / facebookhub / facebookng [.com] unavailable (registered) [.org] available @ $18.00 — over $15 limit [.com] AVAILABLE @ $12.00 ✓ >>> [DRY-RUN] Would register: facebookhub.com @ $12.00 ================================================ Done : 2025-01-15 10:32:14 Registered : 0 Failed : 0 Dupes skipped: 0 Log file : domain-bought.txt Error log : domain-errors.txt ================================================
Prerequisites
Before running the script, ensure you have:
- AWS CLI installed and configured
- An IAM user or role with route53domains:CheckDomainAvailability, route53domains:ListPrices, and route53domains:RegisterDomain permissions
Domain registration costs are charged directly to the AWS account and cannot be easily reversed. Always validate with a dry-run before executing.
Conclusion
What would otherwise require manually checking availability, comparing prices, and filling out registration forms for dozens of domains one at a time is reduced to a single command. The script handles the logic, respects your budget cap, and gives you a clean audit trail of everything it did.