Zapmail domain setup public skill

Public guide: Generate short domain names, check availability, purchase on Dynadot, switch nameservers, set up on Zapmail, create inboxes, and export to your email sending platform.

by growthenginenowoslawski·MIT license·★ 736 Stars on the repo·GitHub ↗

Use now

Files of Zapmail domain setup public

growthenginenowoslawski/main1 file shown
SKILL.md
Show the full text461 lines

Cold Email Domain Setup: Dynadot + Zapmail (Public Edition)

Complete workflow to generate short domain names, purchase them on Dynadot, and set them up on Zapmail with inboxes ready for cold email sending.


First-Time Setup (Onboarding)

Before running anything, you need two API keys stored as environment variables.

1. Get Your Dynadot API Key
  1. Log into dynadot.com
  2. Go to Tools > API in the left sidebar
  3. Enable API access and copy your API key
  4. Whitelist your IP address (required by Dynadot)
2. Get Your Zapmail API Key
  1. Log into zapmail.ai
  2. Go to Settings > API
  3. Copy your API key
3. Store Your Keys

Add these to a .env file in your project root (or export them in your shell):

# .env — NEVER commit this file
DYNADOT_API_KEY=your_dynadot_key_here
ZAPMAIL_API_KEY=your_zapmail_key_here

Load them in your script:

import os
from dotenv import load_dotenv
load_dotenv()

DYNADOT_API_KEY = os.environ["DYNADOT_API_KEY"]
ZAPMAIL_API_KEY = os.environ["ZAPMAIL_API_KEY"]
4. Verify Access

Test both APIs before doing anything:

Dynadot — check wallet balance:

GET https://api.dynadot.com/api3.json?key=<YOUR_KEY>&command=account_info

Response includes AccountBalance (e.g., "$106.20").

Zapmail — list domains:

GET https://api.zapmail.ai/api/v2/domains/assignable?limit=10&page=1
Header: x-auth-zapmail: <YOUR_KEY>

If both return 200, you're ready.


Full Workflow Overview

Step 1: Generate domain name candidates         ~instant
Step 2: Check availability on Dynadot            ~1 min per 500 domains
Step 3: Purchase available domains               ~1 min per 100 domains
   | (domains now registered on Dynadot)
Step 4: Switch nameservers to Zapmail            ~1 min per 500 domains
   | WAIT 15-20 minutes for DNS propagation
Step 5: Connect domains on Zapmail               ~2 min per 500 domains
   | WAIT 10-30 minutes for domains to become assignable
Step 6: Create inboxes on Zapmail                ~3 min per 500 domains
   | WAIT 4-6 HOURS for inbox provisioning
Step 7: Export to your email sending platform    ~instant

Step 1: Generate Short Domain Names

The goal is short, clean domains that look like real brands. Shorter = better deliverability and more professional appearance.

Domain Name Strategy

Use a brand keyword (your company name or a variation) combined with short prefixes/suffixes:

Tier 1 — Prefix + Brand (shortest, try these first):

go{brand}.com       try{brand}.com      get{brand}.com
my{brand}.com       the{brand}.com      hey{brand}.com
use{brand}.com      run{brand}.com      one{brand}.com

Tier 2 — Brand + Suffix (still short):

{brand}hq.com       {brand}hub.com      {brand}now.com
{brand}app.com      {brand}pro.com      {brand}lab.com
{brand}ai.com       {brand}co.com       {brand}go.com

Tier 3 — Prefix + Brand + Suffix (use only if tiers 1-2 don't yield enough):

go{brand}hq.com     try{brand}hub.com   get{brand}pro.com
Full Prefix List (36 options)
go, get, try, join, find, search, explore, reach, access, boost,
team, send, email, connect, launch, start, build, discover, meet,
use, hello, hey, my, the, top, best, run, open, live, grow,
with, via, one, all, new, pro
Full Suffix List (40 options)
hub, hq, online, today, direct, teams, projects, outreach, works,
signal, scope, flow, edge, radar, desk, global, core, base, systems,
engine, link, next, source, circle, stack, zone, path, spot, wave,
grid, point, shift, field, net, way, pulse, vault, peak, sync, lab
Filtering Rules
  • Max SLD length: 40 characters (shorter is always better — aim for under 20)
  • Banned substrings: mega, ultra, grp (look spammy)
  • Awkward substring check: Screen for unintended words (e.g., "therapist" = "the+rapist", profanity, slurs). Run each candidate through a blocklist.
  • Deduplicate globally: Never use the same domain for two different senders/clients
  • .com — primary choice (~$10-14 on Dynadot). Best inbox trust, cleanest pattern-match for recipients.
  • .co — secondary (~$8-30 depending on name). Looks professional, often available when .com is taken.
  • Avoid .info, .xyz, .click, .top, .buzz, .loan — these hurt deliverability with recipients who pattern-match on TLD.
Example: Generating for brand "acme"
Tier 1: goacme.com, tryacme.com, getacme.com, myacme.com ...
Tier 2: acmehq.com, acmehub.com, acmepro.com, acmeflow.com ...
Tier 3: goacmehq.com, tryacmehub.com (only if needed)

For 1 brand keyword, tiers 1+2 produce ~76 candidates. Most brands need 10-30 domains.


Step 2: Check Domain Availability

Dynadot Search API (batch up to 100 per request)
GET https://api.dynadot.com/api3.json
  ?key=<DYNADOT_API_KEY>
  &command=search
  &show_price=1
  &currency=USD
  &domain0=goacme.com
  &domain1=tryacme.com
  &domain2=getacme.com
  ...up to &domain99=...

Response:

{
  "SearchResponse": {
    "SearchResults": [
      {"DomainName": "goacme.com", "Available": "yes", "Price": "2.99"},
      {"DomainName": "tryacme.com", "Available": "no"},
      ...
    ]
  }
}

Important:

  • Max 100 domains per request
  • Add 1 second pause between batches to avoid rate limiting
  • Set a max price cap (recommended: $3.50 for .com)
  • Filter out unavailable domains before proceeding

Step 3: Purchase Domains

Check Wallet Balance First
GET https://api.dynadot.com/api3.json
  ?key=<DYNADOT_API_KEY>
  &command=account_info

Calculate: number_of_domains × price_per_domain. Make sure your balance covers it.

Register Domains (one per API call)
GET https://api.dynadot.com/api3.json
  ?key=<DYNADOT_API_KEY>
  &command=register
  &domain=goacme.com
  &duration=1

Important:

  • One domain per API call (Dynadot doesn't support batch registration)
  • Add 0.5 second pause between registrations
  • Always verify wallet balance before starting
  • duration=1 = 1 year registration

Step 4: Switch Nameservers to Zapmail

After purchase, point each domain's nameservers to Zapmail's DNS.

Zapmail Nameservers
pns61.cloudns.net
pns62.cloudns.com
pns63.cloudns.net
pns64.cloudns.uk
Dynadot NS Switch API (batch up to 100 domains)
GET https://api.dynadot.com/api3.json
  ?key=<DYNADOT_API_KEY>
  &command=set_ns
  &domain=goacme.com,tryacme.com,getacme.com
  &ns0=pns61.cloudns.net
  &ns1=pns62.cloudns.com
  &ns2=pns63.cloudns.net
  &ns3=pns64.cloudns.uk

CRITICAL: Comma encoding bug. When building the URL in Python, default urllib.parse.urlencode() encodes commas as %2C, which breaks the batch request. Fix:

import urllib.parse
params = {
    "key": DYNADOT_API_KEY,
    "command": "set_ns",
    "domain": "goacme.com,tryacme.com,getacme.com",
    "ns0": "pns61.cloudns.net",
    "ns1": "pns62.cloudns.com",
    "ns2": "pns63.cloudns.net",
    "ns3": "pns64.cloudns.uk",
}
url = f"https://api.dynadot.com/api3.json?{urllib.parse.urlencode(params, safe=',')}"

Response:

{"SetNsResponse": {"ResponseCode": 0, "Status": "success"}}
After NS Switch: WAIT 15-20 Minutes

DNS propagation takes time. Don't proceed to Step 5 until at least 15 minutes have passed. 20 minutes is the safe default.


Step 5: Connect Domains on Zapmail

Zapmail Connect API
POST https://api.zapmail.ai/api/v2/domains/connect-domain
Header: x-auth-zapmail: <ZAPMAIL_API_KEY>
Content-Type: application/json

Body: {"domainNames": ["goacme.com", "tryacme.com", "getacme.com"]}

Important:

  • Max 50 domains per request
  • Add 3 second pause between batches
  • Domains go through verification stages: CHECKING_BLACKLISTED_STATUS -> CHECKING_IF_DOMAIN_IS_REGISTERED -> assignable
After Connect: Wait for Domains to Become Assignable

Poll the assignable endpoint to know when you can create inboxes:

GET https://api.zapmail.ai/api/v2/domains/assignable?limit=100&page=1
Header: x-auth-zapmail: <ZAPMAIL_API_KEY>

Typical timeline:

  • 10 minutes: ~8% assignable
  • 20 minutes: ~50-80% assignable
  • 30 minutes: ~99% assignable

Strategy: Poll every 5 minutes. Proceed to inbox creation when >95% of your domains are assignable. The stragglers can be retried later.


Step 6: Create Inboxes

Get Domain UUIDs

First, get the UUIDs for your assignable domains:

GET https://api.zapmail.ai/api/v2/domains/assignable?limit=100&page=1
Header: x-auth-zapmail: <ZAPMAIL_API_KEY>

Match your domain names against the response to get their UUIDs.

Create Mailboxes
POST https://api.zapmail.ai/api/v2/mailboxes
Header: x-auth-zapmail: <ZAPMAIL_API_KEY>
Content-Type: application/json

Body: {
  "<domain-uuid-1>": [
    {"firstName": "Sarah", "lastName": "Chen", "mailboxUsername": "sarah", "domainName": "goacme.com"},
    {"firstName": "Sarah", "lastName": "Chen", "mailboxUsername": "sarahchen", "domainName": "goacme.com"}
  ],
  "<domain-uuid-2>": [
    {"firstName": "Sarah", "lastName": "Chen", "mailboxUsername": "sarah", "domainName": "tryacme.com"},
    {"firstName": "Sarah", "lastName": "Chen", "mailboxUsername": "sarahchen", "domainName": "tryacme.com"}
  ]
}
Inbox Naming Convention

Create 2 inboxes per domain for sending variety:

Important Notes
  • Max 25 domains per request
  • Add 3 second pause between batches
  • Response returns UUID strings, NOT mailbox objects
  • If ANY mailbox in a batch already exists, the ENTIRE batch fails with 400. Handle this by retrying failed domains one at a time.
After Inbox Creation: WAIT 4-6 HOURS

Zapmail returns 200 immediately, but inboxes show "In Progress" status. Full provisioning takes 4-6 hours. Do NOT attempt export until inboxes are ACTIVE.


Step 7: Export to Email Sending Platform

Zapmail Export API
POST https://api.zapmail.ai/api/v2/exports/mailboxes
Header: x-auth-zapmail: <ZAPMAIL_API_KEY>
Content-Type: application/json

Body: {
  "apps": ["SMARTLEAD"],
  "ids": [],
  "excludeIds": [],
  "tagIds": [],
  "contains": "sarah",
  "status": "ACTIVE"
}
Supported Platforms

SMARTLEAD, INSTANTLY, REACHINBOX, REPLY_IO, QUICKMAIL, EMELIA, FIRSTQUADRANT, WARMY, SUPERAGI, LEMLIST, PIPL, LUELLA, MASTER_INBOX, SAILE, SNOV, EMAILBISON

Important
  • Always filter by status: "ACTIVE" — exporting "In Progress" inboxes fails silently
  • Use contains to filter by sender name if you have multiple senders
  • Your sending platform account must be linked first via Zapmail's dashboard or API:
    POST https://api.zapmail.ai/api/v2/exports/accounts/third-party
    Body: {"email": "[email protected]", "password": "your-platform-password", "app": "SMARTLEAD"}
    

Automation: Running End-to-End Unattended

For a fully automated run, chain the steps with appropriate waits:

# 1. Generate & check availability
available_domains = generate_and_check(brand="acme", tld="info", count=30)

# 2. Purchase
purchase_domains(available_domains)

# 3. NS switch
switch_nameservers(available_domains)

# 4. Wait for DNS propagation
time.sleep(20 * 60)  # 20 minutes

# 5. Connect on Zapmail
connect_domains(available_domains)

# 6. Poll until assignable (up to 30 min)
wait_until_assignable(available_domains, timeout_minutes=30, poll_interval=300)

# 7. Create inboxes
create_inboxes(available_domains, first_name="Sarah", last_name="Chen")

# 8. Wait for provisioning
time.sleep(6 * 3600)  # 6 hours

# 9. Export to sending platform
export_to_platform(contains="sarah", app="SMARTLEAD")

Tips for long runs:

  • On macOS, use caffeinate -i to prevent sleep during the 6-hour wait
  • Log each step's results to a file for debugging
  • Send yourself a notification when complete:
    osascript -e 'display notification "All inboxes are live!" with title "Domain Setup Complete"'
    

Common Gotchas

  1. Dynadot comma encoding — urllib.parse.urlencode() encodes commas as %2C, breaking batch NS requests. Always use safe=','.

  2. Batch inbox failures — If even 1 mailbox in a Zapmail batch already exists, the entire batch returns 400. Retry failed domains individually.

  3. Export requires ACTIVE status — Exporting "In Progress" mailboxes fails silently. Always wait the full 4-6 hours or poll for ACTIVE status.

  4. DNS propagation varies — Most domains propagate in 15 min, but some take 30+. Poll the assignable endpoint rather than using a fixed sleep.

  5. Dynadot IP whitelist — API calls will fail if your IP isn't whitelisted in Dynadot's API settings.

  6. Zapmail rate limits — Add pauses between batches (3s for Zapmail, 1s for Dynadot search, 0.5s for Dynadot register). Going too fast gets you temporarily blocked.

  7. Domain length matters — Shorter domains = better deliverability. Prioritize tier 1 (prefix+brand) over tier 3 (prefix+brand+suffix).


Quick Reference: API Endpoints

Action Method URL
Dynadot wallet balance GET https://api.dynadot.com/api3.json?key=KEY&command=account_info
Dynadot search (batch 100) GET https://api.dynadot.com/api3.json?key=KEY&command=search&show_price=1&domain0=...
Dynadot register GET https://api.dynadot.com/api3.json?key=KEY&command=register&domain=X&duration=1
Dynadot NS switch (batch 100) GET https://api.dynadot.com/api3.json?key=KEY&command=set_ns&domain=X,Y&ns0=...
Zapmail connect (batch 50) POST https://api.zapmail.ai/api/v2/domains/connect-domain
Zapmail assignable check GET https://api.zapmail.ai/api/v2/domains/assignable?limit=100&page=N
Zapmail create inboxes (batch 25) POST https://api.zapmail.ai/api/v2/mailboxes
Zapmail export POST https://api.zapmail.ai/api/v2/exports/mailboxes
Zapmail link platform POST https://api.zapmail.ai/api/v2/exports/accounts/third-party

What to do next

Run /smartlead-inbox-manager to configure warmup + signatures + tags on your newly-created inboxes.

Then WAIT 2 WEEKS for warmup before sending real emails. This is the single most important rule — do not skip. Under-warmed inboxes land in spam, damaging your domain reputation permanently.

During the 2-week wait: build your list (/prospeo-full-export, /disco-like, etc.), write copy (/campaign-copywriting). You'll be ready to launch the moment warmup finishes.

  • /smartlead-inbox-manager — configure the inboxes you just provisioned
  • /email-deliverability-audit — check auth records (SPF/DKIM/DMARC) after setup
  • /cold-email-kickoff — the orchestrator that usually invokes this skill
1---
2description: "Public guide: Generate short domain names, check availability, purchase on Dynadot, switch nameservers, set up on Zapmail, create inboxes, and export to your email sending platform. Requires your own Dynadot and Zapmail API keys. Use when someone wants to set up cold email domains end-to-end."
3---
4 
5# Cold Email Domain Setup: Dynadot + Zapmail (Public Edition)
6 
7Complete workflow to generate short domain names, purchase them on Dynadot, and set them up on Zapmail with inboxes ready for cold email sending.
8 
9---
10 
11## First-Time Setup (Onboarding)
12 
13Before running anything, you need two API keys stored as environment variables.
14 
15### 1. Get Your Dynadot API Key
161. Log into [dynadot.com](https://www.dynadot.com)
172. Go to **Tools > API** in the left sidebar
183. Enable API access and copy your API key
194. Whitelist your IP address (required by Dynadot)
20 
21### 2. Get Your Zapmail API Key
221. Log into [zapmail.ai](https://zapmail.ai)
232. Go to **Settings > API**
243. Copy your API key
25 
26### 3. Store Your Keys
27Add these to a `.env` file in your project root (or export them in your shell):
28 
29```bash
30# .env — NEVER commit this file
31DYNADOT_API_KEY=your_dynadot_key_here
32ZAPMAIL_API_KEY=your_zapmail_key_here
33```
34 
35Load them in your script:
36```python
37import os
38from dotenv import load_dotenv
39load_dotenv()
40 
41DYNADOT_API_KEY = os.environ["DYNADOT_API_KEY"]
42ZAPMAIL_API_KEY = os.environ["ZAPMAIL_API_KEY"]
43```
44 
45### 4. Verify Access
46Test both APIs before doing anything:
47 
48**Dynadot — check wallet balance:**
49```
50GET https://api.dynadot.com/api3.json?key=<YOUR_KEY>&command=account_info
51```
52Response includes `AccountBalance` (e.g., `"$106.20"`).
53 
54**Zapmail — list domains:**
55```
56GET https://api.zapmail.ai/api/v2/domains/assignable?limit=10&page=1
57Header: x-auth-zapmail: <YOUR_KEY>
58```
59 
60If both return 200, you're ready.
61 
62---
63 
64## Full Workflow Overview
65 
66```
67Step 1: Generate domain name candidates ~instant
68Step 2: Check availability on Dynadot ~1 min per 500 domains
69Step 3: Purchase available domains ~1 min per 100 domains
70 | (domains now registered on Dynadot)
71Step 4: Switch nameservers to Zapmail ~1 min per 500 domains
72 | WAIT 15-20 minutes for DNS propagation
73Step 5: Connect domains on Zapmail ~2 min per 500 domains
74 | WAIT 10-30 minutes for domains to become assignable
75Step 6: Create inboxes on Zapmail ~3 min per 500 domains
76 | WAIT 4-6 HOURS for inbox provisioning
77Step 7: Export to your email sending platform ~instant
78```
79 
80---
81 
82## Step 1: Generate Short Domain Names
83 
84The goal is **short, clean domains** that look like real brands. Shorter = better deliverability and more professional appearance.
85 
86### Domain Name Strategy
87 
88Use a **brand keyword** (your company name or a variation) combined with short prefixes/suffixes:
89 
90**Tier 1 — Prefix + Brand** (shortest, try these first):
91```
92go{brand}.com try{brand}.com get{brand}.com
93my{brand}.com the{brand}.com hey{brand}.com
94use{brand}.com run{brand}.com one{brand}.com
95```
96 
97**Tier 2 — Brand + Suffix** (still short):
98```
99{brand}hq.com {brand}hub.com {brand}now.com
100{brand}app.com {brand}pro.com {brand}lab.com
101{brand}ai.com {brand}co.com {brand}go.com
102```
103 
104**Tier 3 — Prefix + Brand + Suffix** (use only if tiers 1-2 don't yield enough):
105```
106go{brand}hq.com try{brand}hub.com get{brand}pro.com
107```
108 
109### Full Prefix List (36 options)
110```
111go, get, try, join, find, search, explore, reach, access, boost,
112team, send, email, connect, launch, start, build, discover, meet,
113use, hello, hey, my, the, top, best, run, open, live, grow,
114with, via, one, all, new, pro
115```
116 
117### Full Suffix List (40 options)
118```
119hub, hq, online, today, direct, teams, projects, outreach, works,
120signal, scope, flow, edge, radar, desk, global, core, base, systems,
121engine, link, next, source, circle, stack, zone, path, spot, wave,
122grid, point, shift, field, net, way, pulse, vault, peak, sync, lab
123```
124 
125### Filtering Rules
126- **Max SLD length:** 40 characters (shorter is always better — aim for under 20)
127- **Banned substrings:** mega, ultra, grp (look spammy)
128- **Awkward substring check:** Screen for unintended words (e.g., "therapist" = "the+rapist", profanity, slurs). Run each candidate through a blocklist.
129- **Deduplicate globally:** Never use the same domain for two different senders/clients
130 
131### Recommended TLD
132- `.com` — primary choice (~$10-14 on Dynadot). Best inbox trust, cleanest pattern-match for recipients.
133- `.co` — secondary (~$8-30 depending on name). Looks professional, often available when .com is taken.
134- Avoid `.info`, `.xyz`, `.click`, `.top`, `.buzz`, `.loan` — these hurt deliverability with recipients who pattern-match on TLD.
135 
136### Example: Generating for brand "acme"
137```
138Tier 1: goacme.com, tryacme.com, getacme.com, myacme.com ...
139Tier 2: acmehq.com, acmehub.com, acmepro.com, acmeflow.com ...
140Tier 3: goacmehq.com, tryacmehub.com (only if needed)
141```
142 
143For 1 brand keyword, tiers 1+2 produce ~76 candidates. Most brands need 10-30 domains.
144 
145---
146 
147## Step 2: Check Domain Availability
148 
149### Dynadot Search API (batch up to 100 per request)
150```
151GET https://api.dynadot.com/api3.json
152 ?key=<DYNADOT_API_KEY>
153 &command=search
154 &show_price=1
155 &currency=USD
156 &domain0=goacme.com
157 &domain1=tryacme.com
158 &domain2=getacme.com
159 ...up to &domain99=...
160```
161 
162**Response:**
163```json
164{
165 "SearchResponse": {
166 "SearchResults": [
167 {"DomainName": "goacme.com", "Available": "yes", "Price": "2.99"},
168 {"DomainName": "tryacme.com", "Available": "no"},
169 ...
170 ]
171 }
172}
173```
174 
175**Important:**
176- Max 100 domains per request
177- Add 1 second pause between batches to avoid rate limiting
178- Set a max price cap (recommended: $3.50 for `.com`)
179- Filter out unavailable domains before proceeding
180 
181---
182 
183## Step 3: Purchase Domains
184 
185### Check Wallet Balance First
186```
187GET https://api.dynadot.com/api3.json
188 ?key=<DYNADOT_API_KEY>
189 &command=account_info
190```
191 
192Calculate: `number_of_domains × price_per_domain`. Make sure your balance covers it.
193 
194### Register Domains (one per API call)
195```
196GET https://api.dynadot.com/api3.json
197 ?key=<DYNADOT_API_KEY>
198 &command=register
199 &domain=goacme.com
200 &duration=1
201```
202 
203**Important:**
204- One domain per API call (Dynadot doesn't support batch registration)
205- Add 0.5 second pause between registrations
206- Always verify wallet balance before starting
207- `duration=1` = 1 year registration
208 
209---
210 
211## Step 4: Switch Nameservers to Zapmail
212 
213After purchase, point each domain's nameservers to Zapmail's DNS.
214 
215### Zapmail Nameservers
216```
217pns61.cloudns.net
218pns62.cloudns.com
219pns63.cloudns.net
220pns64.cloudns.uk
221```
222 
223### Dynadot NS Switch API (batch up to 100 domains)
224```
225GET https://api.dynadot.com/api3.json
226 ?key=<DYNADOT_API_KEY>
227 &command=set_ns
228 &domain=goacme.com,tryacme.com,getacme.com
229 &ns0=pns61.cloudns.net
230 &ns1=pns62.cloudns.com
231 &ns2=pns63.cloudns.net
232 &ns3=pns64.cloudns.uk
233```
234 
235**CRITICAL: Comma encoding bug.** When building the URL in Python, default `urllib.parse.urlencode()` encodes commas as `%2C`, which breaks the batch request. Fix:
236```python
237import urllib.parse
238params = {
239 "key": DYNADOT_API_KEY,
240 "command": "set_ns",
241 "domain": "goacme.com,tryacme.com,getacme.com",
242 "ns0": "pns61.cloudns.net",
243 "ns1": "pns62.cloudns.com",
244 "ns2": "pns63.cloudns.net",
245 "ns3": "pns64.cloudns.uk",
246}
247url = f"https://api.dynadot.com/api3.json?{urllib.parse.urlencode(params, safe=',')}"
248```
249 
250**Response:**
251```json
252{"SetNsResponse": {"ResponseCode": 0, "Status": "success"}}
253```
254 
255### After NS Switch: WAIT 15-20 Minutes
256DNS propagation takes time. Don't proceed to Step 5 until at least 15 minutes have passed. 20 minutes is the safe default.
257 
258---
259 
260## Step 5: Connect Domains on Zapmail
261 
262### Zapmail Connect API
263```
264POST https://api.zapmail.ai/api/v2/domains/connect-domain
265Header: x-auth-zapmail: <ZAPMAIL_API_KEY>
266Content-Type: application/json
267 
268Body: {"domainNames": ["goacme.com", "tryacme.com", "getacme.com"]}
269```
270 
271**Important:**
272- Max 50 domains per request
273- Add 3 second pause between batches
274- Domains go through verification stages: `CHECKING_BLACKLISTED_STATUS` -> `CHECKING_IF_DOMAIN_IS_REGISTERED` -> assignable
275 
276### After Connect: Wait for Domains to Become Assignable
277 
278Poll the assignable endpoint to know when you can create inboxes:
279 
280```
281GET https://api.zapmail.ai/api/v2/domains/assignable?limit=100&page=1
282Header: x-auth-zapmail: <ZAPMAIL_API_KEY>
283```
284 
285**Typical timeline:**
286- 10 minutes: ~8% assignable
287- 20 minutes: ~50-80% assignable
288- 30 minutes: ~99% assignable
289 
290**Strategy:** Poll every 5 minutes. Proceed to inbox creation when >95% of your domains are assignable. The stragglers can be retried later.
291 
292---
293 
294## Step 6: Create Inboxes
295 
296### Get Domain UUIDs
297First, get the UUIDs for your assignable domains:
298```
299GET https://api.zapmail.ai/api/v2/domains/assignable?limit=100&page=1
300Header: x-auth-zapmail: <ZAPMAIL_API_KEY>
301```
302 
303Match your domain names against the response to get their UUIDs.
304 
305### Create Mailboxes
306```
307POST https://api.zapmail.ai/api/v2/mailboxes
308Header: x-auth-zapmail: <ZAPMAIL_API_KEY>
309Content-Type: application/json
310 
311Body: {
312 "<domain-uuid-1>": [
313 {"firstName": "Sarah", "lastName": "Chen", "mailboxUsername": "sarah", "domainName": "goacme.com"},
314 {"firstName": "Sarah", "lastName": "Chen", "mailboxUsername": "sarahchen", "domainName": "goacme.com"}
315 ],
316 "<domain-uuid-2>": [
317 {"firstName": "Sarah", "lastName": "Chen", "mailboxUsername": "sarah", "domainName": "tryacme.com"},
318 {"firstName": "Sarah", "lastName": "Chen", "mailboxUsername": "sarahchen", "domainName": "tryacme.com"}
319 ]
320}
321```
322 
323### Inbox Naming Convention
324Create 2 inboxes per domain for sending variety:
325- `{firstname}@domain` (e.g., `[email protected]`)
326- `{firstnamelastname}@domain` (e.g., `[email protected]`)
327 
328### Important Notes
329- Max 25 domains per request
330- Add 3 second pause between batches
331- Response returns UUID strings, NOT mailbox objects
332- **If ANY mailbox in a batch already exists, the ENTIRE batch fails with 400.** Handle this by retrying failed domains one at a time.
333 
334### After Inbox Creation: WAIT 4-6 HOURS
335Zapmail returns 200 immediately, but inboxes show "In Progress" status. Full provisioning takes 4-6 hours. Do NOT attempt export until inboxes are ACTIVE.
336 
337---
338 
339## Step 7: Export to Email Sending Platform
340 
341### Zapmail Export API
342```
343POST https://api.zapmail.ai/api/v2/exports/mailboxes
344Header: x-auth-zapmail: <ZAPMAIL_API_KEY>
345Content-Type: application/json
346 
347Body: {
348 "apps": ["SMARTLEAD"],
349 "ids": [],
350 "excludeIds": [],
351 "tagIds": [],
352 "contains": "sarah",
353 "status": "ACTIVE"
354}
355```
356 
357### Supported Platforms
358`SMARTLEAD`, `INSTANTLY`, `REACHINBOX`, `REPLY_IO`, `QUICKMAIL`, `EMELIA`, `FIRSTQUADRANT`, `WARMY`, `SUPERAGI`, `LEMLIST`, `PIPL`, `LUELLA`, `MASTER_INBOX`, `SAILE`, `SNOV`, `EMAILBISON`
359 
360### Important
361- **Always filter by `status: "ACTIVE"`** — exporting "In Progress" inboxes fails silently
362- Use `contains` to filter by sender name if you have multiple senders
363- Your sending platform account must be linked first via Zapmail's dashboard or API:
364 ```
365 POST https://api.zapmail.ai/api/v2/exports/accounts/third-party
366 Body: {"email": "[email protected]", "password": "your-platform-password", "app": "SMARTLEAD"}
367 ```
368 
369---
370 
371## Automation: Running End-to-End Unattended
372 
373For a fully automated run, chain the steps with appropriate waits:
374 
375```python
376# 1. Generate & check availability
377available_domains = generate_and_check(brand="acme", tld="info", count=30)
378 
379# 2. Purchase
380purchase_domains(available_domains)
381 
382# 3. NS switch
383switch_nameservers(available_domains)
384 
385# 4. Wait for DNS propagation
386time.sleep(20 * 60) # 20 minutes
387 
388# 5. Connect on Zapmail
389connect_domains(available_domains)
390 
391# 6. Poll until assignable (up to 30 min)
392wait_until_assignable(available_domains, timeout_minutes=30, poll_interval=300)
393 
394# 7. Create inboxes
395create_inboxes(available_domains, first_name="Sarah", last_name="Chen")
396 
397# 8. Wait for provisioning
398time.sleep(6 * 3600) # 6 hours
399 
400# 9. Export to sending platform
401export_to_platform(contains="sarah", app="SMARTLEAD")
402```
403 
404**Tips for long runs:**
405- On macOS, use `caffeinate -i` to prevent sleep during the 6-hour wait
406- Log each step's results to a file for debugging
407- Send yourself a notification when complete:
408 ```bash
409 osascript -e 'display notification "All inboxes are live!" with title "Domain Setup Complete"'
410 ```
411 
412---
413 
414## Common Gotchas
415 
4161. **Dynadot comma encoding** — `urllib.parse.urlencode()` encodes commas as `%2C`, breaking batch NS requests. Always use `safe=','`.
417 
4182. **Batch inbox failures** — If even 1 mailbox in a Zapmail batch already exists, the entire batch returns 400. Retry failed domains individually.
419 
4203. **Export requires ACTIVE status** — Exporting "In Progress" mailboxes fails silently. Always wait the full 4-6 hours or poll for ACTIVE status.
421 
4224. **DNS propagation varies** — Most domains propagate in 15 min, but some take 30+. Poll the assignable endpoint rather than using a fixed sleep.
423 
4245. **Dynadot IP whitelist** — API calls will fail if your IP isn't whitelisted in Dynadot's API settings.
425 
4266. **Zapmail rate limits** — Add pauses between batches (3s for Zapmail, 1s for Dynadot search, 0.5s for Dynadot register). Going too fast gets you temporarily blocked.
427 
4287. **Domain length matters** — Shorter domains = better deliverability. Prioritize tier 1 (prefix+brand) over tier 3 (prefix+brand+suffix).
429 
430---
431 
432## Quick Reference: API Endpoints
433 
434| Action | Method | URL |
435|---|---|---|
436| Dynadot wallet balance | GET | `https://api.dynadot.com/api3.json?key=KEY&command=account_info` |
437| Dynadot search (batch 100) | GET | `https://api.dynadot.com/api3.json?key=KEY&command=search&show_price=1&domain0=...` |
438| Dynadot register | GET | `https://api.dynadot.com/api3.json?key=KEY&command=register&domain=X&duration=1` |
439| Dynadot NS switch (batch 100) | GET | `https://api.dynadot.com/api3.json?key=KEY&command=set_ns&domain=X,Y&ns0=...` |
440| Zapmail connect (batch 50) | POST | `https://api.zapmail.ai/api/v2/domains/connect-domain` |
441| Zapmail assignable check | GET | `https://api.zapmail.ai/api/v2/domains/assignable?limit=100&page=N` |
442| Zapmail create inboxes (batch 25) | POST | `https://api.zapmail.ai/api/v2/mailboxes` |
443| Zapmail export | POST | `https://api.zapmail.ai/api/v2/exports/mailboxes` |
444| Zapmail link platform | POST | `https://api.zapmail.ai/api/v2/exports/accounts/third-party` |
445 
446---
447 
448## What to do next
449 
450**Run `/smartlead-inbox-manager`** to configure warmup + signatures + tags on your newly-created inboxes.
451 
452**Then WAIT 2 WEEKS for warmup before sending real emails.** This is the single most important rule — do not skip. Under-warmed inboxes land in spam, damaging your domain reputation permanently.
453 
454**During the 2-week wait:** build your list (`/prospeo-full-export`, `/disco-like`, etc.), write copy (`/campaign-copywriting`). You'll be ready to launch the moment warmup finishes.
455 
456## Related skills
457 
458- `/smartlead-inbox-manager` — configure the inboxes you just provisioned
459- `/email-deliverability-audit` — check auth records (SPF/DKIM/DMARC) after setup
460- `/cold-email-kickoff` — the orchestrator that usually invokes this skill
461 

Discussion